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

如何为CircleAvatar中的图片添加加载效果或微光(Shimmer)效果?

给网络图片添加加载/微光(Shimmer)效果的实现方案

步骤1:添加Shimmer依赖

在你的pubspec.yaml文件里添加shimmer包的依赖:

dependencies:
  shimmer: ^2.0.0

执行flutter pub get完成依赖安装。

步骤2:修改代码实现加载状态控制

先导入shimmer包:

import 'package:shimmer/shimmer.dart';

然后在你的State类里添加状态变量跟踪加载状态,再调整UI构建逻辑:

// 标记服务器图片是否加载完成
bool _isNetworkImageLoaded = false;

@override
void initState() {
  super.initState();
  // 如果存在服务器图片地址,提前预加载图片
  if (_userImage != null && _userImage.isNotEmpty) {
    precacheImage(NetworkImage(_userImage), context).then((_) {
      setState(() {
        _isNetworkImageLoaded = true;
      });
    });
  }
}

// 构建UI部分
child: _image != null 
    // 优先显示本地选择的图片
    ? CircleAvatar(
        backgroundImage: FileImage(_image),
        radius: 75,
        backgroundColor: Colors.grey,
      )
    : (_userImage != null && _userImage.isNotEmpty)
        // 根据加载状态切换显示微光占位或真实图片
        ? _isNetworkImageLoaded
            ? CircleAvatar(
                backgroundImage: NetworkImage(_userImage),
                radius: 75,
                backgroundColor: Colors.grey,
              )
            : Shimmer.fromColors(
                baseColor: Colors.grey[300]!,
                highlightColor: Colors.grey[100]!,
                child: CircleAvatar(
                  radius: 75,
                  backgroundColor: Colors.grey,
                ),
              )
        // 无服务器图片时显示默认占位图
        : CircleAvatar(
            backgroundImage: AssetImage(DrawableResource.imagePlaceHolder),
            radius: 75,
            backgroundColor: Colors.grey,
          ),

原理说明

  • 用precacheImage预加载网络图片,加载完成后更新状态变量,触发UI重绘显示真实图片。
  • 加载过程中,Shimmer.fromColors生成和CircleAvatar尺寸一致的微光占位,baseColor和highlightColor可根据你的UI风格自定义调整。
  • 保留原有图片优先级逻辑:本地选择图 > 服务器图 > 默认占位图。

无第三方包的简易方案(可选)

如果不想依赖第三方包,可以用AnimatedContainer做一个简单的渐变加载动画(效果不如Shimmer精致):

// 简易加载占位动画
child: AnimatedContainer(
  duration: Duration(milliseconds: 1000),
  curve: Curves.easeInOut,
  decoration: BoxDecoration(
    shape: BoxShape.circle,
    gradient: LinearGradient(
      begin: Alignment.left,
      end: Alignment.right,
      colors: [Colors.grey[300]!, Colors.grey[100]!, Colors.grey[300]!],
    ),
  ),
),

需要配合AnimationController控制渐变位置循环,才能实现持续动画效果。

内容的提问来源于stack exchange,提问作者Rajesh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:06:24