美文网首页
TabBar组件实践 2023-07-22 周六

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

作者: 松哥888 | 来源:发表于2023-07-23 10:30 被阅读0次

简介

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

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

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

  • 使用系统提供的TabBarTabBarView套装

  • 使用ContainerListView等模拟

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

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

  • TabBarView只是一个容器,所以UI的难度集中在TabBar

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

文本间距

  • Tab底层应该是类似ListView的实现,等分是不大好做的;

  • 可以通过labelPadding这个属性模拟;tab少的时候大一些,tab多的时候小一些;

指示器大小

  • 对应的属性是indicatorSize

  • 默认是和tab容器宽度一样TabBarIndicatorSize.tab

  • 按照设计图,这里要改为TabBarIndicatorSize.label, 和tab的文字一样长度;

指示器pad

  • 对应的属性是indicatorPadding

  • 默认都是0,所以是和文字一样宽度,紧贴底部;

  • 这里,按照设计图给一下就好;

  • 另外,指示器和tab内容应该用了stack,两者不是一个图层。所以,设置indicatorPadding可以改变指示器和文本之间的间距。

指示器形状

  • 如果只是调整一下颜色和粗细,可以设置这两个属性
    this.indicatorColor,
    this.indicatorWeight = 2.0,
  • 如果需要圆角,那么就需要使用this.indicator属性;同时,上面两个属性失效

  • this.indicator的类型是Decoration;但是这个是虚基类,真正有用的是UnderlineTabIndicator

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

tabs

  • 类型定义是普通的Widgetfinal List<Widget> tabs;

  • 但是,实际上一般都是给Tab组件

const Tab({
    super.key,
    this.text,
    this.icon,
    this.iconMargin = const EdgeInsets.only(bottom: 10.0),
    this.height,
    this.child,
  })
  • 从定义上看,可以是文字,也可以是图片,也可以是自定义widget;但是实际上,大多数情况是文本。

  • 所以,这里简单处理,就是直接规定为文本

        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);
  }

指示器固定大小

  • 系统提供的指示器,宽度给了两种模式,和容器一样(加padding),或者和文字一样(加偏移)

  • 指示器给出的是方角,不是圆角。

  • 如果要求指示器固定宽度,并且是圆角,那么就需要自定义UnderlineTabIndicator

  • 做法也很取消,就是复制UnderlineTabIndicator的内容,改个名字,然后稍微修改一下代码。

  • 具体做法这篇文章写的非常清楚:Flutter tabbar自定义indicator的固定宽度、圆角

参考文章

flutter tabBar 的属性及自定义实现

Flutter UnderlineTabIndicator BoxDecoration ShapeDecoration FlutterLogoDecoration

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

相关文章

  • uniapp自定义tabbar

    App.vue中隐藏系统tabbar 创建tabbar组件 页面引用tabbar组件

  • 小程序-自定义tabbar

    新建组件 tabbar.wxml tabbar.wxss tabbar.js tabbar.json app.js...

  • React项目实战二

    1, 实现tabBar 1,使用步骤1,打开antd-mobile组件中的TabBar组件的文档[https://...

  • 封装tabbar栏

    一共4个tabbar栏这里省略... 子组件: tabbar.vue 子组件可以使用 $emit 触发父组件的自定...

  • 底部TabBar

    组件分解 页面显示组件:Scaffold底部Tabbar组件:BottomNavigationBar底部Tabba...

  • 微信小程序之首页

    1.底部导航栏写法一:组件tabbar tabbar组件api 在app.json文件中加入以下代码,"color...

  • tabBar组件

    一. 全局配置 我们可以通过对项目根目录下的app.json文件实现对微信小程序的全局配置,该文件的内容是一个Js...

  • tabbar与item

    item.vue HelloWorld.vue ( tabbar组件 )

  • flutter 之 TabBar、TabBarView的使用

    TabBar还有TabBarView都是谷歌flutter官方组件库——Material组件库提供的组件,其中Ta...

  • Ant Design Mobile 组件学习经验

    使用过的组件 TabBar、Toast、ActivityIndicator、Button、SegmentedCon...

网友评论

      本文标题:TabBar组件实践 2023-07-22 周六

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