美文网首页
Flutter仿Boss-6.底部tab切换

Flutter仿Boss-6.底部tab切换

作者: 一笑轮回吧 | 来源:发表于2024-04-08 22:21 被阅读0次

    效果

    boss_tab.gif

    实现

    • 图片资源采用boss包中的动画webp资源。
    • Flutter采用Image加载webp动画。

    遇到的问题

    问题:Flutter加载webp再次加载无法再次播放动画问题

    看如下代码:

    Image.asset(
         'assets/images/xxx.webp',
         width: 40.w,
         height: 30.w,
    )
    

    运行的效果:

    屏幕录制2024-04-09 22.14.41.gif

    直接采用上面代码加载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,
    )
    

    再运行下效果:


    boss_tab.gif

    完整源码

    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

    相关文章

      网友评论

          本文标题:Flutter仿Boss-6.底部tab切换

          本文链接:https://www.haomeiwen.com/subject/pgxatjtx.html