Flutter 自定義 TabBar

aiguangyuan發表於2020-12-27

TabBar常用於放在AppBar中,以標籤頁的形式展示同一個頁面不同內容的主題標籤。

常見的屬性如下:

1. tabs 標籤組。值的型別為Widget列表;

2. controller 標籤控制器。值的型別為TabController;

3. isScrollable 標籤組是否可以滾動。值的型別為bool;

4. indicatorColor 指示器的顏色。值的型別為Colors;

5. indicatorWeight 指示器權重,即顯示高度。值的型別為double;

6. indicatorPadding 指示器的內邊距。值的型別為EdgeInsets;

7. indicator 指標器裝飾。值的型別為Decoration;

8. indicatorSize 指示器的大小。值的型別為TabBarIndicatorSize,常用的值為TabBarIndicatorSize.label;

9. labelColor 標籤的顏色。值的型別為Colors;

10. labelStyle 標籤的樣式。值的型別為TextStyle;

11. labelPadding 標籤的內邊距。值的型別為EdgeInsets;

12. unselectedLabelColor 選中標籤的顏色。值的型別為Colors;

13. unselectedLabelStyle 選中標籤的樣式。值的型別為TextStyle;

 

1. 實現一個普通的Tab選項卡

程式碼示例:

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
    const HomePage({Key key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
        // 新增頂部導航條
        return DefaultTabController(
            // 切換的數量
            length:2, 
            child: Scaffold(
                appBar: AppBar(
                    // App標題
                    title:Text('Flutter App'),
                    // 無論什麼平臺,標題都居中
                    centerTitle: true,
                    // 背景顏色
                    backgroundColor: Colors.red,
                    // 標籤欄
                    bottom: TabBar(
                        // 指示器的大小
                        indicatorSize: TabBarIndicatorSize.label,
                        // 標籤
                        tabs: <Widget>[
                            Tab(text:"熱門"),
                            Tab(text:"推薦")
                        ],
                    ),  
                ),
                // 標籤頁所對應的頁面
                body:TabBarView(
                    children: <Widget>[
                        ListView(
                            children:<Widget>[
                                Center(child:ListTile(
                                    title:Text("熱門內容")
                                ))
                            ]
                        ),
                        ListView(
                            children:<Widget>[
                                ListTile(
                                    title:Text("推薦內容")
                                )
                            ]
                        )
                    ],
                )
            )
        );
    }
} 

效果圖如下:

 

2. 實現常見App的選項卡效果

程式碼如下:

// lib/pages/tabs/Gategory.dart
import "package:flutter/material.dart";

// 分類頁面
class CategoryPage extends StatefulWidget {
    CategoryPage({Key key}) : super(key: key);
    _CategoryPageState createState() => _CategoryPageState();
}

class _CategoryPageState extends State<CategoryPage> {
    @override
    Widget build(BuildContext context) {
        return DefaultTabController(
            // 標籤數量
            length: 9, 
            child:Scaffold(
                appBar: AppBar(
                    title:Row(
                        children: <Widget>[
                            // 彈性容器佈局
                            Expanded(
                                child:TabBar(
                                    // 多個標籤時滾動載入
                                    isScrollable:true,
                                    // 標籤指示器的顏色
                                    indicatorColor: Colors.red,
                                    // 標籤的顏色
                                    labelColor: Colors.black,
                                    // 未選中標籤的顏色
                                    unselectedLabelColor: Colors.white,
                                    // 指示器的大小
                                    indicatorSize: TabBarIndicatorSize.label,
                                    // 指示器的權重,即線條高度
                                    indicatorWeight: 4.0,

                                    tabs: <Widget>[
                                        Tab(text:"熱銷"),
                                        Tab(text:"推薦"),
                                        Tab(text:"搞笑"),
                                        Tab(text:"妙招"),
                                        Tab(text:"關注"),
                                        Tab(text:"時尚"),
                                        Tab(text:"女性"),
                                        Tab(text:"服裝"),
                                        Tab(text:"男性"),
                                    ],
                                )
                            )
                        ],
                    )
                ),
                // 標籤頁所對應的頁面
                body:TabBarView(
                    children: <Widget>[
                        ListView(
                            children:<Widget>[
                                ListTile(
                                    title:Text("熱銷內容")
                                )
                            ]
                        ),
                        ListView(
                            children:<Widget>[
                                ListTile(
                                    title:Text("推薦內容")
                                )
                            ]
                        ),
                        ListView(
                            children:<Widget>[
                                ListTile(
                                    title:Text("搞笑內容")
                                )
                            ]
                        ),
                        ListView(
                            children:<Widget>[
                                ListTile(
                                    title:Text("妙招內容")
                                )
                            ]
                        ),
                        ListView(
                            children:<Widget>[
                                ListTile(
                                    title:Text("關注內容")
                                )
                            ]
                        ),
                         ListView(
                            children:<Widget>[
                                ListTile(
                                    title:Text("時尚內容")
                                )
                            ]
                        ),
                        ListView(
                            children:<Widget>[
                                ListTile(
                                    title:Text("女性內容")
                                )
                            ]
                        ),
                         ListView(
                            children:<Widget>[
                                ListTile(
                                    title:Text("服裝內容")
                                )
                            ]
                        ),
                        ListView(
                            children:<Widget>[
                                ListTile(
                                    title:Text("男性內容")
                                )
                            ]
                        ),
                    ],
                )
            )
        );
    }
}

效果圖如下:

 

3. 自定義帶控制器Tab選項卡

程式碼如下:

// lib/pages/tabs/Setting.dart
import "package:flutter/material.dart";

// 設定頁面
class SettingPage extends StatefulWidget {
    SettingPage({Key key}) : super(key: key);
    _SettingPageState createState() => _SettingPageState();
}


// 混入 SingleTickerProviderStateMixin 這個類
class _SettingPageState extends State<SettingPage> with SingleTickerProviderStateMixin {
    
    // 標籤控制器
    TabController _tabController;
    @override
    // 初始化載入-生命週期函式
    void initState() {
        super.initState();
        // 定義控制器
        _tabController = new TabController(
            vsync: this,
            length: 2, 
        );
        // 新增監聽事件
        _tabController.addListener((){
            print(_tabController.index);
        });
    }
    // 關閉銷燬-生命週期函式
    @override
    void dispose() {
        super.dispose();
        // 殺死控制器
        _tabController.dispose();
    }

    @override
    Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
                title: Text('設定頁面'),
                bottom: TabBar(
                    // 加上控制器
                    controller: this._tabController,
                    tabs: <Widget>[
                        Tab(text:'熱門'),
                        Tab(text:'推薦'),
                    ],
                ),
            ),
            body: TabBarView(
                // 加上控制器
                controller: this._tabController,
                children: <Widget>[
                    Center(child:Text('熱門頁面')),
                    Center(child:Text('推薦頁面')),
                ],
            ),
        );
    }
}

效果圖如下:

上面這個自定義的Tab選項卡看起來很簡單,但是由於加入了控制器,在實際專案中可以運用控制器實現一些複雜的頁面互動。

相關文章