能否在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
相关产品推荐
相关产品推荐

