You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为图片同时添加加载时的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 22:45:30