Flutter 仿掘金之动态Tabbar

    xiaoxiao2023-10-21  30

    效果

    不多逼逼

    Tabbar

    先看Tabbar的参数

    const TabBar({ Key key, @required this.tabs, // item this.controller, //控制器 this.isScrollable = false, //是否可以滑动 this.indicatorColor, //指示器的颜色 this.indicatorWeight = 2.0, this.indicatorPadding = EdgeInsets.zero, this.indicator,//自定义指示器 this.indicatorSize, this.labelColor, // 选中文字颜色 this.labelStyle, // this.labelPadding, // 文字的内边距 this.unselectedLabelColor, // 未选中文字颜色 this.unselectedLabelStyle, this.dragStartBehavior = DragStartBehavior.start, this.onTap,// 点击事件 })

    TabBarView

    const TabBarView({ Key key, @required this.children, // 每页的view this.controller, // 控制器 this.physics, this.dragStartBehavior = DragStartBehavior.start, })

    好了,这两个必须关联起来用. 不然会报错

    DefaultTabController

    这个是一个无状态的控制器,很简单.但是要做成动态Tabbar的话,不能用这个.

    TabController

    也很简单.

    TabController({ int initialIndex = 0, @required this.length, @required TickerProvider vsync })

    主要是这个TickerProvider.作用是获取每一帧刷新的通知.

    其实也简单

    直接 实现TickerProviderStateMixin就好了.

    class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin{ TabController _tabController; @override void initState() { super.initState(); _tabController = new TabController(length: _spList.length, vsync: this);// 直接传this } }

    如何动态创建

    SharedPreferences 这里我使用了本地缓存来做的

    添加插件

    写个工具

    class SpUtils { static Future<List<String>> getSpList(String key) async { SharedPreferences prefs = await SharedPreferences.getInstance(); return prefs.getStringList(key) ?? []; } static setSpList(String key, List<String> list) async { SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setStringList(key, list); } }

    这样使用就简单很多了


    完整的代码

    import 'package:flutter/material.dart'; import '../util/SpUtils.dart'; class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin { var _bottomIndex = 0; var _spList = []; TabController _tabController; @override void initState() { super.initState(); _tabController = new TabController(length: _spList.length, vsync: this); } @override Widget build(BuildContext context) { SpUtils.getSpList('tabmenu').then((s) { if (_spList == s) { return; } setState(() { _spList = s; _tabController = new TabController(length: _spList.length, vsync: this); }); }); return Scaffold( appBar: new AppBar( titleSpacing: 0, title: Center( child: new TabBar( controller: _tabController, isScrollable: true, labelColor: Colors.white, tabs: _spList.map((f) { return Center( child: new Text(f), ); }).toList(), ), ), actions: <Widget>[ new Container( child: new Icon(Icons.arrow_drop_down), width: 48, ) ], ), body: TabBarView( controller: _tabController, children: _spList.isEmpty ? [] : _spList.map((f) { return Center( child: new Text(f), ); }).toList()), floatingActionButton: FloatingActionButton( onPressed: () {}, tooltip: 'Increment', child: Icon(Icons.add), ), bottomNavigationBar: new BottomNavigationBar( items: [ new BottomNavigationBarItem( icon: Icon(Icons.home), title: new Container(), ), new BottomNavigationBarItem( icon: Icon(Icons.whatshot), title: new Container(), ), new BottomNavigationBarItem( icon: Icon(Icons.search), title: new Container(), ), new BottomNavigationBarItem( icon: Icon(Icons.book), title: new Container(), ), new BottomNavigationBarItem( icon: Icon(Icons.person), title: new Container(), ), ], currentIndex: _bottomIndex, type: BottomNavigationBarType.fixed, backgroundColor: Colors.white, selectedItemColor: Colors.blue, unselectedItemColor: Colors.grey, onTap: (i) { setState(() { _bottomIndex = i; }); }, ), ); } }

    注意的点:

    1._tabController 要重新创建.因为需要更新长度

    setState(() { _spList = s; _tabController = new TabController(length: _spList.length, vsync: this); })

    2.Tabbar放Appbard的title位置上

    TabBar需要使用center包装.不然默认高度是不会占满的,当然也可以用其它办法

    isScrollable需要设置为true.才能滑动.

    appBar: new AppBar( titleSpacing: 0, title: Center( child: new TabBar( controller: _tabController, isScrollable: true, labelColor: Colors.white, tabs: _spList.map((f) { return Center( child: new Text(f), ); }).toList(), ), ), actions: <Widget>[ new Container( child: new Icon(Icons.arrow_drop_down), width: 48, ) ], ),

    最后

    你怎么没说怎么动态的呢!

    很简单.只要更新SharedPreferences的缓存值.就可以了.像 掘金的效果是跨页面开关的.所以使用SharedPreferences的缓存来做


    期待你的留言 点赞

    交流群:

    Flutter:782978118

    Android:493180098

    最新回复(0)