Flutter 实现TabBar的两种方式

顶部TabLayout的实现

TabBar是作为AppBar的一部分存在。Flutter SDK中提供了两种实现顶部TabLayout的方法,两者效果是一样的,但第二种功能更为丰富。具体为 TabBar + TabBarView两个weight结合。
在这里插入图片描述
话不多说上代码:

方法一:DefaultTabController

使用 DefaultTabController作为最外层控制器,联调 TabBar + TabBarView,这种方式简单方便,但致命缺点是拿不到当前选中tab的index

class FirstPage extends StatefulWidget {
  FirstPage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  State<StatefulWidget> createState() => _FirstPageState();
}

/// DefaultTabController (TabBar + TabBarView) 使用 (内部还是TabController实现)
class _FirstPageState extends State<FirstPage> {
  final List<Tab> myTabs = <Tab>[
    Tab(text: '全部订单'),
    Tab(text: '已完成'),
    Tab(text: '未完成')
  ];

  @override
  Widget build(BuildContext context) {
	// 1. 使用 DefaultTabController 作为外层控制器
    return DefaultTabController(
      length: myTabs.length,// 定义tab数量
      child: Scaffold(
        appBar: AppBar(
          title: Text('FirstPage'),
          
		  // 2. 使用 TabBar
          bottom: TabBar(
            tabs: myTabs // 定义TabWeight,若数量和定义不一致会报错
          ),
        ),
		
		// 3. 使用 TabBarView
        body: TabBarView(
            children: <Widget>[
        
              /// 全部订单
              Center(child: Text('全部订单')),
        
              /// 已完成订单
              Center(child: Text('已完成')),
        
              /// 未完成订单
              Center(child: Text('未完成'))
            ]),
      ),
    );
  }
}

效果如下:
在这里插入图片描述

方法二:TabController

实现SingleTickerProviderStateMixin,重写初始化和注销方法,利用控制器TabController管理和更多操作,其实第一种方法内部也是由TabController实现的。

// 1. 实现 SingleTickerProviderStateMixin 
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  TabController _tabController;
  
  static const List<Tab> _homeTopTabList = <Tab>[
    Tab(text: '音乐', icon: Icon(Icons.music_note)),
    Tab(text: '体育', icon: Icon(Icons.directions_run)),
    Tab(text: '天气', icon: Icon(Icons.cloud_queue)),
    Tab(text: '科技', icon: Icon(Icons.toys))
  ];

  // 2. 初始化状态
  @override
  void initState() {
    super.initState();
    // TabController的滚动事件会触发一次监听, 点击事件会触发两次监听(一次是正常触发,一次是tab的动画触发)
    _tabController = TabController(length: _homeTopTabList.length, vsync: this);
    
    // 添加监听获取tab选中下标
    _tabController.addListener((){
      _currentTopTabIndex = _tabController.index;
    });
  }
  
  // 3. 注销状态
  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
          
          // 4. 添加TabBar
          bottom: TabBar(
            tabs: _homeTopTabList,
            controller: _tabController
          ),
        ),

		// 5. 添加TabBarView
        body: TabBarView(
          controller: _tabController,
          children: <Widget>[
            _tabMusic(context),
            _tabSport(context),
            _tabSport(context),
            _tabSport(context)
          ],
        ),
       );
  }

关于TabController 的监听有个坑 踩坑TabBar之TabController.addListener

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柯基爱蹦跶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值