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

能否在Shimmer容器中嵌套其他容器实现指定加载效果?

使用shimmer包实现目标加载效果的问题

我正在使用shimmer包制作加载页面,当前效果如下:
已实现的Shimmer效果

我想要制作如下样式的Shimmer加载框:
目标Shimmer效果

我的代码如下:

class _Shimmer extends StatelessWidget {
  const _Shimmer();

  @override
  Widget build(BuildContext context) {
    return Shimmer.fromColors(
      baseColor: Colors.grey.shade300,
      highlightColor: Colors.grey.shade100,
      enabled: true,
      child: SingleChildScrollView(
        physics: const NeverScrollableScrollPhysics(),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          children: [
            const SizedBox(height: 40),
            ...List.generate(
              10,
              (index) => const Column(
                children: [
                  _CardPlaceHolder(),
                  SizedBox(height: 16),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _CardPlaceHolder extends StatelessWidget {
  const _CardPlaceHolder({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          width: double.infinity,
          height: 86,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(18.0),
            color: Colors.white,
          ),
        ),
      ],
    );
  }
}

当我在主容器中添加另一个容器作为子组件时,该容器无法显示。请问是否可以通过该包实现目标效果,还是需要创建新的Shimmer组件?


解决方案:完全可以用现有shimmer包实现目标效果

问题出在当前的_CardPlaceHolder仅使用白色背景容器,添加子容器不显示是因为子容器颜色和父容器一致(均为白色),被shimmer效果覆盖后无视觉差异。要实现目标的分栏+内部小块加载效果,只需修改_CardPlaceHolder的布局,用不同灰度的容器来模拟内容占位即可。

修改后的_CardPlaceHolder示例:

class _CardPlaceHolder extends StatelessWidget {
  const _CardPlaceHolder({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: 86,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(18.0),
        color: Colors.grey.shade300, // 用shimmer的baseColor作为底色
      ),
      child: Padding(
        padding: const EdgeInsets.all(12.0),
        child: Row(
          children: [
            // 左侧圆形占位
            Container(
              width: 60,
              height: 60,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(12),
                color: Colors.grey.shade200, // 比底色浅,配合shimmer动画
              ),
            ),
            const SizedBox(width: 12),
            // 右侧文字区域占位
            Expanded(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Container(
                    width: double.infinity,
                    height: 16,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(4),
                      color: Colors.grey.shade200,
                    ),
                  ),
                  const SizedBox(height: 8),
                  Container(
                    width: 150, // 模拟短文本宽度
                    height: 14,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(4),
                      color: Colors.grey.shade200,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

关键说明:

  • 将原白色容器替换为与shimmer baseColor接近的灰色,子容器使用稍浅的灰色,shimmer动画扫过时会产生明暗变化,呈现分层效果
  • 无需创建新组件,Shimmer.fromColors会对所有子组件的颜色做动画处理,只要子容器与父容器底色有差异,就能实现目标的分块加载效果
  • 之前子容器不显示是因为颜色与父容器一致,换成不同灰度的灰色即可解决

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:30:20