Flutter 之 TabBar & TabBarView

直接上图上代码,代码部分有注释,莫有的自己百度(留言也可以);

效果图.png

class TestDemo extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _TestDemoState();
  }
}

class _TestDemoState extends State<TestDemo>
    with SingleTickerProviderStateMixin {
  TabController mController;
  List<String> tabTitles;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _appBarView(),
      body: _tabBarView(),
    );
  }

  @override
  void dispose() {
    super.dispose();
    mController.dispose();
  }

  @override
  void initState() {
    super.initState();
    tabTitles = [
      "tab1",
      "tab2",
      "tab3",
      "tab4",
      "tab5",
      "tab6",
      "tab7",
      "tab8",
      "tab9",
    ];

    mController = TabController(
      length: tabTitles.length,
      vsync: this,
    );
  }

  Widget _appBarView() {
    return AppBar(
      title: Text("TabBar & TabBarView",
          style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold)),
      elevation: 0,
      bottom: _tabBar(),
    );
  }

  Widget _tabBar() {
    return TabBar(
        //设置tab是否可水平滑动
        isScrollable: true,
        //控制器
        controller: mController,
        //设置tab文字得类型
        labelStyle: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
        //设置tab选中得颜色
        labelColor: Colors.black,
        //设置tab未选中得颜色
        unselectedLabelColor: Colors.black45,
        //设置自定义tab的指示器,CustomUnderlineTabIndicator
        //若不需要自定义,可直接通过
        //indicatorColor 设置指示器颜色
        //indicatorWight 设置指示器厚度
        //indicatorPadding
        //indicatorSize  设置指示器大小计算方式
        indicator: CustomUnderlineTabIndicator(
            strokeCap: StrokeCap.round,
            insets: EdgeInsets.only(left: 15, right: 15),
            borderSide: BorderSide(width: 4.0, color: Colors.red)),
        tabs: tabTitles.map((item) {
          return Tab(text: item);
        }).toList());
  }

  Widget _tabBarView() {
    return TabBarView(
      controller: mController,
      children: tabTitles.map((item) {
        return Container(
          color: _getColor(),
          child: Center(
            child: Text(item,
                style: TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                    color: Colors.white)),
          ),
        );
      }).toList(),
    );
  }

  Color _getColor() {
    var random = new Random();
    int r = random.nextInt(255);
    int g = random.nextInt(255);
    int b = random.nextInt(255);
    print(r);
    print(g);
    print(b);
    return Color.fromARGB(255, r, g, b);
  }

}

TabBarView

这里的children直接使用了Container显示效果,所以在切换的时候,并没有问题出现。但一般情况,我们都会为TabBarView的子类自定义一个Widget,并且会在这个Widget的 initState() 方法里面进行数据的初始化。这时候切换Tab,会发现界面又初始化了?~
(网传)Flutter中为了节约内存不会保存widget的状态,widget都是临时变量。所以,每次切换重修的时候,都会调用 initState() 方法

解决:

在对应的Widget里面的State类,继承AutomaticKeepAliveClientMixin抽象类,并且重写方法,返回true,强制widget不被销毁:

  @override
  bool get wantKeepAlive => true;

PS:widget在不显示也会强制保存在内存中,所以需要合理使用。

CustomUnderlineTabIndicator 自定义圆角指示器

最简单的,参考UnderlineTabIndicator(代码90行),对Ponit的画笔做了参数自定义。StrokeCap使用了.round的方式,就能实现。



作者:Grey_zbb
链接:https://www.jianshu.com/p/68fa1c725415
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值