[Flutter ] 自定义一个标签栏tabBar

效果一
在这里插入图片描述
效果二
在这里插入图片描述
效果三
在这里插入图片描述

代码

  /// 头部视图绘制
  List<Widget> headItems() {
    var list = homeController.categoryClist.value.list ?? [];
    var items = <Widget>[];
    for (int i = 0; i < list.length; i++) {
      items.add(
        GestureDetector(
            onTap: () {
              setState(() {
                tabIndex = i;
              });
            },
            child: Container(
              /// item容器一, 用于动态修改底色, 方便圆角的视觉展示
              decoration: boxDecorationByIndex(i)[0],
              child: Container(
                  width: (343.w / list.length),
                  height: 35.h,
                  /// item内容容器, 用于动态修改底色/圆角等(选中/非选中), 方便圆角的视觉展示
                  decoration: boxDecorationByIndex(i)[1],
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      TDText(
                        list[i].cname,
                        style: TextStyle(fontSize: 15.sp, color: ColorUtil.greenSub01),
                        fontWeight: tabIndex == i ? FontWeight.bold : null,
                      )
                    ],
                  )),
            )),
      );
    }
    return items;
  }

  // 根据选中的tabIndex返回对应的 boxDecoreation
  // 第一个装饰器是作为第一个Container容器的背景色, 根据选中状态来动态调整
  // 第二个装饰器用于选中/非选中的 item控制UI样式
  List<BoxDecoration> boxDecorationByIndex(int index) {
    var list = homeController.categoryClist.value.list ?? [];
    Radius radius = Radius.circular(10.w);
    // 选中 状态
    if (tabIndex == index) {
      // 选中 头
      if (index == 0) {
        return [
          BoxDecoration(color: ColorUtil.darkTextSub04, borderRadius: BorderRadius.only(topLeft: radius)),
          BoxDecoration(color: ColorUtil.whiteMain, borderRadius: BorderRadius.only(topLeft: radius, topRight: radius)),
        ];
      }

      // 选中 尾
      if (index == list.length - 1) {
        return [
          BoxDecoration(
            color: ColorUtil.darkTextSub04,
            borderRadius: BorderRadius.only(topRight: radius),
          ),
          BoxDecoration(color: ColorUtil.whiteMain, borderRadius: BorderRadius.only(topLeft: radius, topRight: radius))
        ];
      }

      // 选中 中间
      if (index > 0 && index < list.length - 1) {
        return [
          const BoxDecoration(
            color: ColorUtil.darkTextSub04,
          ),
          BoxDecoration(color: ColorUtil.whiteMain, borderRadius: BorderRadius.only(topLeft: radius, topRight: radius))
        ];
      }
    }
    // 非选中状态
    else {
      // 非选中 - 如果选中的是头部,处理头部右侧第一个的特殊情况
      if (tabIndex == 0 && index == 1) {
        return [
          const BoxDecoration(
            color: ColorUtil.whiteMain,
          ),
          BoxDecoration(color: ColorUtil.darkTextSub04, borderRadius: BorderRadius.only(bottomLeft: radius))
        ];
      }

      // 非选中 - 如果选中的是尾部,处理尾部左侧第一个的特殊情况
      if (tabIndex == list.length - 1 && index == list.length - 2) {
        return [
          const BoxDecoration(
            color: ColorUtil.whiteMain,
          ),
          BoxDecoration(color: ColorUtil.darkTextSub04, borderRadius: BorderRadius.only(bottomRight: radius))
        ];
      }
      // 非选中 - 中间的情况处理
      else {
        // 非选中 - 处理当前选中的左侧的情况
        if(tabIndex-1==index){
          return [
            const BoxDecoration(
              color: ColorUtil.whiteMain,
            ),
            BoxDecoration(
                color: ColorUtil.darkTextSub04, borderRadius: BorderRadius.only( bottomRight: radius))
          ];
        }
        // 非选中 - 处理当前选中的右侧的情况
        if(tabIndex+1==index){
          return [
            const BoxDecoration(
              color: ColorUtil.whiteMain,
            ),
            BoxDecoration(
                color: ColorUtil.darkTextSub04, borderRadius: BorderRadius.only(bottomLeft: radius))
          ];
        }
        // 非选中 , 其他不项链的默认处理
        else{
          return [
            const BoxDecoration(
              color: ColorUtil.whiteMain,
            ),
            const BoxDecoration(
                color: ColorUtil.darkTextSub04, )
          ];
        }
      }
    }

    return [BoxDecoration(), BoxDecoration()];
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值