如何为CachedNetworkImage()添加Ink.image()的水波纹点击效果?
我正好处理过类似的场景,给你两个实用的解决方案,帮你兼顾CachedNetworkImage的占位符功能和Ink的水波纹效果:
方案1:用InkWell直接包裹CachedNetworkImage(推荐)
这是最直观的实现方式,InkWell本身就提供点击水波纹效果,只要确保它在Material组件内部(因为Ink的视觉效果依赖Material作为绘制画布)。
Material( // 设置为页面背景色,避免出现突兀的色块 color: Colors.transparent, child: InkWell( onTap: () { /* 这里写你的点击逻辑 */ }, // 自定义水波纹颜色和透明度 splashColor: Colors.blue.withOpacity(0.3), highlightColor: Colors.grey.withOpacity(0.1), child: CachedNetworkImage( fit: BoxFit.fitWidth, imageUrl: product.imageUrl, // 加载中的占位符 placeholder: (context, url) => const Center(child: CircularProgressIndicator()), // 加载失败时的占位符 errorWidget: (context, url, error) => const Icon(Icons.error_outline, color: Colors.grey), ), ), )
注意:如果你的CachedNetworkImage显示的是不透明图片,水波纹会绘制在图片下方,可能看不到效果。这种情况下方案2会更适合你。
方案2:结合CachedNetworkImageProvider与Ink.image
如果你特别想保留Ink.image的用法,可以用CachedNetworkImageProvider(它是ImageProvider的子类,能复用CachedNetworkImage的缓存机制),然后通过Stack来实现占位符效果:
Material( child: InkWell( onTap: () { /* 你的点击逻辑 */ }, child: Stack( fit: StackFit.expand, children: [ // 用CachedNetworkImageProvider作为Ink.image的数据源 Ink.image( fit: BoxFit.fitWidth, image: CachedNetworkImageProvider(product.imageUrl), ), // 加载状态占位符:图片加载完成前显示,加载完成后隐藏 FutureBuilder<ImageStreamCompleter>( future: CachedNetworkImageProvider(product.imageUrl) .resolve(const ImageConfiguration()) .completed, builder: (context, snapshot) { if (snapshot.connectionState != ConnectionState.done) { return const Center(child: CircularProgressIndicator()); } // 加载完成后返回空组件 return const SizedBox.shrink(); }, ), ], ), ), )
这个方案既保留了Ink.image的原生水波纹效果,又利用了CachedNetworkImage的缓存能力,同时通过FutureBuilder来处理加载状态的占位符。你还可以在FutureBuilder里添加错误处理逻辑,比如判断snapshot.hasError时显示错误图标。
内容的提问来源于stack exchange,提问作者Mateen Kiani
相关产品推荐
相关产品推荐

