TabBar组件实践 2023-07-22 周六

2023-07-23  本文已影响0人  勇往直前888

简介

原先的工程中用了TabBar,最简单的那种。现在UI提出了优化要求,那么就要在原先的基础上进行样式修改。

企业微信截图_6f86b386-831b-4c4c-89cf-d32bc6f8c0dc.png

选择:系统组件还是自定义?

经过纠结,最终还是决定用TabBarTabBarView套装,通过给出的属性来逐步达到目的;

使用ContainerListView等模拟这种方式,实在没办法的时候再考虑;

TabBar常用属性

高度

class TabBar extends StatefulWidget implements PreferredSizeWidget可以看出,TabBar是一种PreferredSizeWidget。所以,可以考虑把TabBar放到一个PreferredSize组件中,高度就根据tabs的数量来

@override
  Widget build(BuildContext context) {
    double height = 30.h;
    if (tabs.length < 4) {
      height = 44.h;
    }
    return PreferredSize(
      preferredSize: Size.fromHeight(height),
      child: TabBar(
        tabs: tabs,
      ),
    );
  }

控制器

这个是TabBarTabBarView联动的纽带,大多数情况是需要的,只需要按照原来的定义透传就可以了。

文本

    this.labelColor,
    this.labelStyle,
    this.unselectedLabelColor,
    this.unselectedLabelStyle,

滑动切换

这个默认是this.isScrollable = false,;通常要改为true

文本间距

指示器大小

指示器pad

指示器形状

    this.indicatorColor,
    this.indicatorWeight = 2.0,
        indicator: UnderlineTabIndicator(
          borderRadius: BorderRadius.circular(1.5.h),
          borderSide: BorderSide(
            color: const Color(0xFF11BA66),
            width: 3.h,
          ),
        ),

tabs

const Tab({
    super.key,
    this.text,
    this.icon,
    this.iconMargin = const EdgeInsets.only(bottom: 10.0),
    this.height,
    this.child,
  })
        tabs: textList
            .map((text) => Tab(
                  text: text,
                ))
            .toList(),

封装为组件

由于Flutter的特性,就像套娃一样一层层嵌套。所以考虑在外面TabBar外面套一层,把上面那些讨论过的属性定义封装起来。

class PandaTabBar extends StatelessWidget implements PreferredSizeWidget {
  const PandaTabBar({
    Key? key,
    required this.textList,
    this.controller,
  }) : super(key: key);

  final TabController? controller;
  final List<String> textList;

  @override
  Widget build(BuildContext context) {
    /// 参数判空
    if (textList.isEmpty) {
      return Container();
    }

    /// Tab个数4个以下,高度44;其他情况,高度30
    /// 文本之间的间距,4个以下,40;其他情况15
    double height = 30.h;
    double pad = 15.w;
    if (textList.length < 4) {
      height = 44.h;
      pad = 40.w;
    }
    return PreferredSize(
      preferredSize: Size.fromHeight(height),
      child: TabBar(
        controller: controller,
        labelColor: const Color(0xFF11BA66),
        unselectedLabelColor: PandaColorConfig().col333333,
        labelStyle: TextStyle(
          fontSize: 16.sp,
          fontWeight: FontWeight.w500,
        ),
        unselectedLabelStyle: TextStyle(
          fontSize: 16.sp,
          fontWeight: FontWeight.w400,
        ),
        isScrollable: true,
        labelPadding: EdgeInsets.symmetric(horizontal: pad),
        indicatorSize: TabBarIndicatorSize.label,
        indicatorPadding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 9.h),
        indicator: UnderlineTabIndicator(
          borderRadius: BorderRadius.circular(1.5.h),
          borderSide: BorderSide(
            color: const Color(0xFF11BA66),
            width: 3.h,
          ),
        ),
        tabs: textList
            .map((text) => Tab(
                  text: text,
                ))
            .toList(),
      ),
    );

  @override
  Size get preferredSize => Size.fromHeight(44.h);
  }

指示器固定大小

参考文章

flutter tabBar 的属性及自定义实现

Flutter UnderlineTabIndicator BoxDecoration ShapeDecoration FlutterLogoDecoration

Flutter设置TabBar indicator宽度(爆改UnderlineTabIndicator )

上一篇 下一篇

猜你喜欢

热点阅读