您的位置:

Flutter Tab组件详解

Flutter Tab组件是Flutter中很常用的一种组件,通常用于分组展示信息,或者展示不同的页面。在这篇文章中,我们将会从多个方面详细阐述Flutter Tab组件的使用方法和注意事项。

一、创建基本的Tab组件

在Flutter中,我们可以使用Material Design风格的Tab,下面我们来看一个最基本的Tab组件:


import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final List
    tabs = 
    [
    Tab(text: 'Tab1'),
    Tab(text: 'Tab2'),
    Tab(text: 'Tab3'),
  ];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: tabs.length,
        child: Scaffold(
          appBar: AppBar(
            title: Text('Flutter Tab Demo'),
            bottom: TabBar(
              tabs: tabs,
            ),
          ),
          body: TabBarView(
            children: 
     [
              Center(child: Text('This is Tab1')),
              Center(child: Text('This is Tab2')),
              Center(child: Text('This is Tab3')),
            ],
          ),
        ),
      ),
    );
  }
}

     
    
   

我们首先定义了一个包含三个Tab的List,然后在home中使用DefaultTabController包装Scaffold、AppBar和TabBarView便可实现默认的Tab组件,上方显示AppBar,下方使用了TabBar,TabView中展示三个页面,页面之间能够通过Tab进行切换。

二、自定义Tab样式

默认情况下,Tab的样式比较简单,但是我们完全可以自定义它的样式,比如Tab高度、字体样式等等。下面我们将Tab高度调整至30像素,并且将字体设为16像素:


class MyApp extends StatelessWidget {
  final List
    tabs = 
    [
    Tab(text: 'Tab1'),
    Tab(text: 'Tab2'),
    Tab(text: 'Tab3'),
  ];

  final TextStyle tabBarTextStyle =
      TextStyle(fontSize: 16, fontWeight: FontWeight.w500);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: tabs.length,
        child: Scaffold(
          appBar: AppBar(
            title: Text('Flutter Tab Demo'),
            bottom: PreferredSize(
              preferredSize: Size.fromHeight(30.0),
              child: TabBar(
                tabs: tabs,
                labelStyle: tabBarTextStyle,
              ),
            ),
          ),
          body: TabBarView(
            children: 
     [
              Center(child: Text('This is Tab1')),
              Center(child: Text('This is Tab2')),
              Center(child: Text('This is Tab3')),
            ],
          ),
        ),
      ),
    );
  }
}

     
    
   

在这个例子中,我们定义了一个TextStyle对象,将Tab字体设为16像素、加粗的样式。然后在TabBar的labelStyle中使用了这个TextStyle对象,Tab高度通过PreferredSize调整,实现了更加美观的Tab效果。

三、动态添加或删除Tab

在一些特殊情况下,我们需要动态添加或删除Tab,例如根据服务器数据返回的结果生成Tab。下面我们将演示动态添加一个Tab的方法:


class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State
    {
  final List
     tabs = 
     [];
  int tabIndex = 0;

  @override
  void initState() {
    super.initState();
    tabs.add(Tab(text: 'Tab1'));
    tabs.add(Tab(text: 'Tab2'));
  }

  void addTab() {
    setState(() {
      tabIndex++;
      tabs.add(Tab(text: 'Tab$tabIndex'));
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: tabs.length,
        child: Scaffold(
          appBar: AppBar(
            title: Text('Flutter Tab Demo'),
            bottom: TabBar(
              tabs: tabs,
            ),
          ),
          body: TabBarView(
            children: tabs.map((Tab tab) {
              return Center(child: Text('This is ${tab.text}'));
            }).toList(),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: addTab,
            child: Icon(Icons.add),
          ),
        ),
      ),
    );
  }
}

     
    
   

在这个例子中,我们定义了一个空的Tab List,在initState方法中添加了两个Tab。然后我们在FloatingActionButton的onPressed方法中动态添加了一个Tab对象并刷新页面。

四、更加复杂的Tab使用场景

在实际开发中,我们可能需要更加复杂的Tab使用场景,例如Tab左侧显示一个icon,右侧显示一个Badge等等。下面我们将展示一个更好的Tab组件实现方法,包含左侧icon、右侧Badge、动画效果等等。


import 'package:flutter/material.dart';

class ComplexTab extends StatefulWidget {
  @override
  _ComplexTabState createState() => _ComplexTabState();
}

class _ComplexTabState extends State
    {
  final List
     tabs = 
     [
    _buildTab(icon: Icons.home, badgeCount: 5),
    _buildTab(icon: Icons.mail, badgeCount: 3),
    _buildTab(icon: Icons.person, badgeCount: 8),
  ];

  static Widget _buildTab({IconData icon, int badgeCount}) {
    return Stack(
      children: 
      [
        Tab(
          icon: Icon(icon),
        ),
        Visibility(
          visible: badgeCount > 0,
          child: Positioned(
            top: 0,
            right: 0,
            child: Container(
              padding: EdgeInsets.all(1),
              decoration: BoxDecoration(
                color: Colors.red,
                borderRadius: BorderRadius.circular(10),
              ),
              constraints: BoxConstraints(
                minWidth: 18,
                minHeight: 18,
              ),
              child: Text(
                '$badgeCount',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 12,
                ),
                textAlign: TextAlign.center,
              ),
            ),
          ),
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: tabs.length,
      child: Scaffold(
        appBar: AppBar(
          title: Text('Complex Tab Demo'),
          bottom: TabBar(
            tabs: tabs,
            isScrollable: true,
            indicatorColor: Colors.transparent,
            onTap: (index) {
              setState(() {});
            },
          ),
        ),
        body: TabBarView(
          children: tabs.map((Widget widget) {
            return Center(child: widget);
          }).toList(),
        ),
      ),
    );
  }
}

      
     
    
   

在这个例子中,我们定义了一个包含三个Widget的List,每个Widget都是一个Stack,包含了左侧icon和右侧Badge。右侧Badge通过一个包装有Text的Container实现,在数量变化时进行显示或隐藏操作,使用Visibility能够使badge不占据空间。TabBar中设置isScrollable为true时,当Tab数量非常多时会出现滚动条,增加用户体验,同时我们还加入Tab切换动画。

五、结语

到这里,我们已经阐述了Flutter Tab组件的使用方法和注意事项,可以用于实现基本的Tab组件和复杂的Tab组件。在实际开发中,我们能够根据需要自由地进行选择,实现自己的需求。