【Flutter學習】基本組件之TabBar頂部導航


一,概述

  TabBar,是材料設計(Material design)中很常用的一種橫向標簽頁。在Android原生開發中,我們常用ViewPage或者一些常用的標簽頁開源庫,來實現並行界面的橫向滑動展示,在iOS原生開發中我們可以基於UICollectionView/UIButton來封裝實現這一功能,在Flutter的世界中,TabBar是被定義在Material Component中,所以他的使用需要在MaterialApp中。通常,我們會在AppBar的底部部分結合TabBarView來使用TabBar。
    


二,Tab關鍵元素

  • TabController
    這是Tab頁的控制器,用於定義Tab標簽和內容頁的坐標,還可配置標簽頁的切換動畫效果等。
    TabController一般放入有狀態控件中使用,以適應標簽頁數量和內容有動態變化的場景,如果標簽頁在APP中是靜態固定的格局,則可以在無狀態控件中加入簡易版的DefaultTabController以提高運行效率,畢竟無狀態控件要比有狀態控件更省資源,運行效率更快。
  • TabBar
    Tab頁的Title控件,切換Tab頁的入口,一般放到AppBar控件下使用,內部有*Title屬性。其子元素按水平橫向排列布局,如果需要縱向排列,請使用ColumnListView控件包裝一下。子元素為Tab類型的數組
  • TabBarView
    Tab頁的內容容器,其內放置Tab頁的主體內容。子元素可以是多個各種類型的控件。

三,構造函數  

  • TabController
    • DefalutTabController
       const DefaultTabController({
          Key key,
          @required this.length,
          this.initialIndex = 0,
          @required this.child,
        }) : assert(initialIndex != null),
             assert(length >= 0),
             assert(initialIndex >= 0 && initialIndex < length),
             super(key: key);
    • TabController
      TabController({ int initialIndex = 0, @required this.length, @required TickerProvider vsync })
          : assert(length != null && length >= 0),
            assert(initialIndex != null && initialIndex >= 0 && (length == 0 || initialIndex < length)),
            _index = initialIndex,
            _previousIndex = initialIndex,
            _animationController = AnimationController.unbounded(
              value: initialIndex.toDouble(),
              vsync: vsync,
            );
  • TabBar
    /**
        const TabBar({
        Key key,
        @required this.tabs,//顯示的標簽內容,一般使用Tab對象,也可以是其他的Widget
        this.controller,//TabController對象
        this.isScrollable = false,//是否可滾動
        this.indicatorColor,//指示器顏色
        this.indicatorWeight = 2.0,//指示器高度
        this.indicatorPadding = EdgeInsets.zero,//底部指示器的Padding
        this.indicator,//指示器decoration,例如邊框等
        this.indicatorSize,//指示器大小計算方式,TabBarIndicatorSize.label跟文字等寬,TabBarIndicatorSize.tab跟每個tab等寬
        this.labelColor,//選中label顏色
        this.labelStyle,//選中label的Style
        this.labelPadding,//每個label的padding值
        this.unselectedLabelColor,//未選中label顏色
        this.unselectedLabelStyle,//未選中label的Style
        }) : assert(tabs != null),
        assert(isScrollable != null),
        assert(indicator != null || (indicatorWeight != null && indicatorWeight > 0.0)),
        assert(indicator != null || (indicatorPadding != null)),
        super(key: key);
     */
    • Tab
      const Tab({
          Key key,
          this.text,
          this.icon,
          this.child,
        }) : assert(text != null || child != null || icon != null),
             assert(!(text != null && null != child)), // TODO(goderbauer): https://github.com/dart-lang/sdk/issues/34180
             super(key: key);
  • TabBarView
      const TabBarView({
        Key key,
        @required this.children, //Tab頁內容頁組件數組集合
        this.controller, //TabController對象
        this.physics,
        this.dragStartBehavior = DragStartBehavior.start,
      }) : assert(children != null),
           assert(dragStartBehavior != null),
           super(key: key);

四,創建標簽欄

  • 1.創建TabController
    • 使用默認的DefaultController
       /**2.創建Tabbar */
        @override
        Widget build(BuildContext context) {
          // TODO: implement build
          return new DefaultTabController(
              length: myTabs.length,
              child:  new Scaffold(
                //AppBar
                appBar:new AppBar(
                  title: new Text('頂部標簽欄'),
                  bottom: new TabBar(
                    tabs: myTabs, //標簽數組
                    indicatorColor: Colors.blue,//指示器的顏色
                    isScrollable: true,//是否滑動
                  ),
                ) ,
      
        /**3.綁定Tabbar 和 TabBarView */
                //body
                body: new TabBarView(
                  children: myTabs.map((Tab tab){
                      return new Center( child: new Text(tab.text));
                  }).toList(),
                ),
              ),
          );
        }
    • 使用自定義的TabController的
      class TabBarDemoState extends State<TabBarDemo>
          with SingleTickerProviderStateMixin {
        TabController _tabController; //定義tabcontroller變量
      
        @override
        void dispose() {
          _tabController.dispose(); //銷毀
          super.dispose();
        }
      
        void initState() {
          super.initState();
          _tabController = new TabController(vsync: this, length: 3); //創建
        }
      
        @override
        Widget build(BuildContext context) {
          return new Scaffold(
            appBar: new AppBar(
              title: new Text('頂部tab切換'),
              bottom: new TabBar(
                tabs: <Widget>[
                  new Tab(
                    icon: new Icon(Icons.directions_bike),
                  ),
                  new Tab(
                    icon: new Icon(Icons.directions_boat),
                  ),
                  new Tab(
                    icon: new Icon(Icons.directions_bus),
                  ),
                ],
                controller: _tabController, //tabbar與自定義的tabcontroller綁定
              ),
            ),
            body: new TabBarView(
              controller: _tabController, //tabbarView與 自定義的tabController綁定
              children: <Widget>[
                new Center(child: new Text('自行車')),
                new Center(child: new Text('')),
                new Center(child: new Text('巴士')),
              ],
            ),
          );
        }
  • 2.構建Tab數據/TabBarView數據
    /**1. 創建Tab數據 */
      final List<Tab> myTabs = <Tab>[
          new Tab(icon: new Icon(Icons.home),
          text:'首頁',
          ),
          new Tab(
            icon: new Icon(Icons.message),
             text:'個人信息',
          ),
          
          new Tab(
            icon: new Icon(Icons.camera),
            text:'朋友圈',
          ),
          new Tab(
            icon: new Icon(Icons.access_alarm),
            text: '鬧鍾',
          )
      ];
  • 3. 創建Tabbar
    appBar:new AppBar(
                title: new Text('頂部標簽欄'),
                bottom: new TabBar(
                  tabs: myTabs, //標簽數組
                  indicatorColor: Colors.blue,//指示器的顏色
                  isScrollable: true,//是否滑動
                ),
    )
  • 4.綁定TabBar 和 TabBarView
    /**3.綁定Tabbar 和 TabBarView */
              //body
              body: new TabBarView(
                children: myTabs.map((Tab tab){
                    return new Center( child: new Text(tab.text));
                }).toList(),
              ),
  • 5.全部代碼
    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
        // TODO: implement build
        return new MaterialApp(
          title: '頂部標簽欄',
          theme: new ThemeData(
            primaryColor: Colors.red
          ),
          home: new App(),
        );
      }
    }
    
    class App extends StatelessWidget {
    
      /**1. 創建Tab數據 */
      final List<Tab> myTabs = <Tab>[
          new Tab(icon: new Icon(Icons.home),
          text:'首頁',
          ),
          new Tab(
            icon: new Icon(Icons.message),
             text:'個人信息',
          ),
          
          new Tab(
            icon: new Icon(Icons.camera),
            text:'朋友圈',
          ),
          new Tab(
            icon: new Icon(Icons.access_alarm),
            text: '鬧鍾',
          )
      ];
       
      /**2.創建Tabbar */
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return new DefaultTabController(
            length: myTabs.length,
            child:  new Scaffold(
              //AppBar
              appBar:new AppBar(
                title: new Text('頂部標簽欄'),
                bottom: new TabBar(
                  tabs: myTabs, //綁定標簽數組
                  indicatorColor: Colors.blue,//指示器的顏色
                  isScrollable: true,//是否滑動
                ),
              ) ,
    
      /**3.綁定Tabbar 和 TabBarView */
              //body
              body: new TabBarView(
                children: myTabs.map((Tab tab){
                    return new Center( child: new Text(tab.text));
                }).toList(),
              ),
            ),
        );
      }
    }

五,總結

TabBarView和TabBar都有一個TabController的參數,TabbarView和TabBar就是由TabController來控制同步,點擊某個Tab后,要同步顯示對應的TabBarView,創建TabController有兩種方式:

  • 第一種:使用系統自帶的DefaultTabController,在Scaffold套一層DefaultTabController,這種方式TabBarView會自動查找這個tabController。
    @override
    Widget build(BuildContext context) {
       return new DefaultTabController();
    }
  • 第二種是自己定義一個TabController,實現SingleTickerProviderStateMixin
    參考上面“使用自定tabcontroller代碼”

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM