如何为图片同时添加加载时的Shimmer效果与按压时的InkWell水波纹效果?
实现方法
方案1:自定义组合组件(无需依赖第三方Shimmer包)
直接通过Stack、基础shimmer包、InkWell和Material组合,既能实现加载时的渐隐动画,又能触发水波纹效果:
import 'package:flutter/material.dart'; import 'package:shimmer/shimmer.dart'; class ShimmerInkImage extends StatelessWidget { final String imageUrl; final double width; final double height; final VoidCallback onTap; const ShimmerInkImage({ super.key, required this.imageUrl, required this.width, required this.height, required this.onTap, }); @override Widget build(BuildContext context) { return Material( color: Colors.transparent, // 保持背景透明,不影响外层布局 child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(8), // 可选,和图片圆角匹配 child: ClipRRect( borderRadius: BorderRadius.circular(8), child: Stack( fit: StackFit.expand, children: [ // 加载中的Shimmer动画 Shimmer.fromColors( baseColor: Colors.grey[300]!, highlightColor: Colors.grey[100]!, child: Container(color: Colors.grey[300]), ), // 网络图片,加载完成后覆盖Shimmer Image.network( imageUrl, fit: BoxFit.cover, loadingBuilder: (context, child, loadingProgress) { if (loadingProgress == null) return child; return const SizedBox.shrink(); // 加载中隐藏图片,透出下层Shimmer }, errorBuilder: (context, error, stackTrace) { return const Icon(Icons.error, color: Colors.red); }, ), ], ), ), ), ); } }
方案2:结合fancy_shimmer_image实现
如果一定要用fancy_shimmer_image包,只需注意把它嵌套在InkWell内部,同时外层套Material来激活水波纹:
import 'package:flutter/material.dart'; import 'package:fancy_shimmer_image/fancy_shimmer_image.dart'; class FancyShimmerInkImage extends StatelessWidget { final String imageUrl; final double width; final double height; final VoidCallback onTap; const FancyShimmerInkImage({ super.key, required this.imageUrl, required this.width, required this.height, required this.onTap, }); @override Widget build(BuildContext context) { return Material( color: Colors.transparent, child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(8), child: ClipRRect( borderRadius: BorderRadius.circular(8), child: FancyShimmerImage( width: width, height: height, boxFit: BoxFit.cover, imageUrl: imageUrl, errorWidget: const Icon(Icons.error, color: Colors.red), ), ), ), ); } }
核心注意事项
- 必须用
Material包裹InkWell:Flutter的水波纹效果依赖Material组件的上下文,没有它InkWell的水波纹不会显示。 - 统一圆角设置:如果需要圆角,要保证
InkWell、ClipRRect和图片的圆角一致,避免水波纹超出图片范围。 - 加载状态控制:方案1通过
loadingBuilder手动控制图片显隐;方案2依赖fancy_shimmer_image内置的加载动画,无需额外处理。
内容的提问来源于stack exchange,提问作者jeiea
相关产品推荐
相关产品推荐

