效果
实现
- 图片资源采用boss包中的动画webp资源。
- Flutter采用Image加载webp动画。
遇到的问题
问题:Flutter加载webp再次加载无法再次播放动画问题
看如下代码:
Image.asset( 'assets/images/xxx.webp', width: 40.w, height: 30.w, )
运行的效果:
直接采用上面代码加载webp动画图片的时候,发现首次加载是没有问题的,当切换其他tab再次切换回来的时候,虽然我重新setState了,但是图片不会重新动画加载出来。开始觉得很奇怪,Image都重新创建了,为啥动画不重新执行呢?心想难道有缓存,想当然就给Image定义了key,每次点击按钮给Image设置不同的key,运行发现还是不行,到这一步只好谷歌大法了,看到了很多人遇到这个问题,但是没有给出解决的答案,看来只能源码大法了。
源码走起~~这里省略…
然后发现Image中有内存缓存ImageCache,翻看了源码后发现了解决方案,因为这里我不需要内存缓存,而且这个缓存与Image中的bundle有关系,只要每次创建Image设置不同的bundle就OK了,所以我就把代码尝试修改了下。
Image.asset( 'assets/images/xxx.webp', bundle: PlatformAssetBundle(), width: 40.w, height: 30.w, )
再运行下效果:
完整源码
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_project/res/colors/color_res.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; /// BottomBarItem class BottomBarItem extends StatefulWidget { // Tab 名字 final String tabName; // Tab 图标 final String tabIcon; // Tab 选中图标 final String tabSelectedIcon; // 默认颜色 final Color tabTextColor; // 选中颜色 final Color tabTextSelectedColor; // Tab对应索引 final int tabIndex; // 点击回调 final Function(int) onTap; // 是否选中 final bool isChecked; // 角标 final int badger; const BottomBarItem({ Key? key, required this.tabName, required this.tabIcon, required this.tabSelectedIcon, required this.onTap, required this.tabIndex, this.tabTextColor = Colors.grey, this.tabTextSelectedColor = RC.themeColor, this.isChecked = false, this.badger = 0, }) : super(key: key); @override State<BottomBarItem> createState() => _BottomBarItemState(); } class _BottomBarItemState extends State<BottomBarItem> { @override Widget build(BuildContext context) { return InkWell( child: Stack( children: [ Positioned( child: Container( alignment: Alignment.center, child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start, children: [ widget.isChecked ? Image.asset( widget.tabSelectedIcon, bundle: PlatformAssetBundle(), width: 40.w, height: 30.w, ) : Image.asset( widget.tabIcon, width: 40.w, height: 30.w, ), Text( widget.tabName, style: TextStyle( color: widget.isChecked ? widget.tabTextSelectedColor : widget.tabTextColor, fontSize: 10.sp, ), ), ], ), ), ), Visibility( visible: widget.badger > 0, child: Positioned( right: 30.w, top: 10.w, child: ClipOval( child: Container( alignment: Alignment.center, color: Colors.red, width: 8, height: 8, ), ), ), ) ], ), onTap: () { widget.onTap(widget.tabIndex); setState(() {}); }, ); } }
具体详情:github.com/yixiaolunhui/flutter_project