如何自定义 Flutter 中的 Tab Bar?

4

我想自定义我的TabBar

目前我有这个TabBar(默认UI):

stock TabBar

我希望拥有这个UI:

desired TabBar

我已经编写了个性化的选项卡,但不知道如何实现它。

这是关于我的HomePage的当前代码:

class HomePage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new HomePageState();
  }
}

class HomePageState extends State<HomePage>
    with SingleTickerProviderStateMixin {
  TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController =
        TabController(length: 6, vsync: this); // initialise it here
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          bottom: TabBar(
            controller: _tabController,
            isScrollable: true,
            tabs: [
              Tab(text: "NewPay1.1"),
              Tab(text: "NewMall 1.0"),
              Tab(text: "海报"),
              Tab(text: "企业版"),
              Tab(text: "个版"),
              Tab(text: "poa"),
            ],
          ),
          title: Text('tabBar'),
        ),
        body: TabBarView(
          controller: _tabController,
          children: [
            // these are your pages
            TaskListPage(),
            TestPage(),
          ],
        ),
        bottomNavigationBar: BottomAppBar(
          color: Colors.white,
          shape: CircularNotchedRectangle(),
          child: Row(
            children: <Widget>[
              IconButton(
                onPressed: () => _tabController.animateTo(0),
                icon: Icon(Icons.home),
              ),
              SizedBox(),
              IconButton(
                  onPressed: () => _tabController.animateTo(1),
                  icon: Icon(Icons.more))
            ],
            mainAxisAlignment: MainAxisAlignment.spaceAround,
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            return TestPage().createState();
          },
          child: Icon(Icons.add),
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      ),
    );
  }
}

那么我的CustomTab类:
class CustomTab extends StatefulWidget {

  final Function(int) tabSelected;
  final List<String> items;

  const CustomTab({Key key, this.tabSelected, this.items}) : super(key: key);

  @override
  _CustomTabState createState() => _CustomTabState();
}

class _CustomTabState extends State<CustomTab> {
  var categorySelected = 0;

  @override
  Widget build(BuildContext context) {
    return _getListCategory();
  }

  Widget _getListCategory(){

    ListView listCategory = new ListView.builder(
        itemCount: widget.items.length,
        scrollDirection: Axis.horizontal,
        itemBuilder: (context, index){
          return _buildCategoryItem(index);
        }
    );

    return new Container(
      height: 50.0,
      child: listCategory,
      color: Colors.grey[200].withAlpha(200),
    );

  }

  Widget _buildCategoryItem(index){

    return new InkWell(
      onTap: (){
        setSelectedItem(index);
        print("click");
      },
      child: new Row(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          new Container(
            margin: new EdgeInsets.only(left: 10.0),
            child: new Material(
              elevation: 2.0,
              color: categorySelected == index ? Colors.black : Colors.grey,
              borderRadius: const BorderRadius.all(const Radius.circular(25.0)),
              child:  new Container(
                padding: new EdgeInsets.only(left: 12.0,top: 7.0,bottom: 7.0,right: 12.0),
                child: new Text(widget.items[index],
                  style: new TextStyle(
                    color: categorySelected == index ? Colors.white : Colors.black),
                ),
              ),
            ),
          )
        ],
      ),
    );

  }

  void setSelectedItem(index) {

    if(index != categorySelected) {
      widget.tabSelected(index);
      setState(() {
        categorySelected = index;
      });
    }
  }
}

1
你可以尝试使用这个包 https://pub.dartlang.org/packages/bubble_tab_indicator - Rishabh
请查看此链接:https://android.jlelse.eu/flutter-bubble-tab-indicator-for-tabbar-dd038f1076d3。 - Kalpesh Kundanani
1
请查看以下链接 https://mightytechno.com/how-to-style-tabs-in-flutter-app/ 。 - Ishan Fernando
@IshanFernando 有没有办法只在选中标签时显示标签名称? - Nithin Sai
3个回答

2

需要为“已选”和“未选”选项卡使用两种不同的样式,例如两种不同的背景和边框颜色。但是似乎没有任何示例! - SKMohammadi
有没有办法只在选中选项卡时显示选项卡名称? - Nithin Sai

0
tabAlignment: TabAlignment.start, 只需添加这个
        bottom: const TabBar(
          tabAlignment: TabAlignment.start,  // here twist 
          isScrollable: true,
          tabs: [
            Tab(text: 'Tab 1'),
            Tab(text: 'Tab 2'),
            Tab(text: 'Tab 3'),
          ],
        ),

-1

尝试这段代码,它非常简单

首先初始化这个

var radius = Radius.circular(150);

那么

class _Class_Name extends State<ClassName> {
  var radius = Radius.circular(150);

  @override
  Widget build(BuildContext context) {
      length: 2,
      child: Scaffold(
          appBar: AppBar(
            elevation: 0,
            backgroundColor: Colors.white,
            centerTitle: true,
            leading: // if you need
            ),
            title:
               // if you need
   // Scrollable rounded Tab bar        
          body: TabBar(
                isScrollable: true,
                labelColor: Colors.black,
                tabs: <Widget>[
                  Tab(
                    text: "Tab 1",
                  ),
                  Tab(
                    text: "Tab 2",
                  ),
                ],
                indicator: ShapeDecoration(
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.all(radius)),
                    color: HexColor('#005866')),
              ),
              Container(
                height: 80,
                child: TabBarView(
                  children: <Widget>[
                    Container(
                      child: Center(
                        child: Text("Hello"),
                      ),
                    ),
                    Container(
                      child: Center(
                        child: Text("Hi"),
                      ),
                    ),
                    ),
                  ],
                ),
              ),
    );
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接