flutter:BottomNavigationBar和TabBar

区别

BottomNavigationBarr和TabBar都是用于创建导航栏的组件,但它们有一些区别。

  1. 位置不同:BottomNavigationBar通常位于屏幕底部,用于主要导航;而TabBar通常位于屏幕顶部或底部,用于切换不同的视图或页面。

  2. 样式不同:BottomNavigationBar是一个水平的导航栏,通常包含固定数量的图标和标签。它提供了固定的样式,并且可以自动处理选中和未选中状态的切换。

    TabBar可以水平或垂直显示,通常用于展示多个选项卡。它提供了更多的自定义选项,比如可以设置自定义的标签样式、背景色等。

  3. 功能不同:BottomNavigationBar通常用于在不同的主页面之间进行导航,每个图标对应一个页面。它的功能相对简单,适用于主要导航。

    TabBar用于切换不同的视图或页面,并且可以与TabBarView一起使用来展示与每个选项卡对应的内容。它在应用程序中的使用场景更加广泛,适用于切换和展示多个相关页面或功能。

总之,BottomNavigationBar适用于简单的主导航,TabBar适用于更复杂的页面切换和内容展示。

示例:来源于qq阅读

BottomNavigationBar

TabBar

BottomNavigationBar

BottomNavigationBar是Flutter中用于创建底部导航栏的组件。它通常与TabBarView一起使用,用于在不同的选项卡之间切换内容。

BottomNavigationBar有一个items属性,其中可以定义导航栏的每个选项卡。每个选项卡都可以包含一个图标和一个文本标签。

dart 复制代码
class SwitcherContainer extends StatefulWidget {
  const SwitcherContainer({Key? key}) : super(key: key);

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

class SwitcherContainerState extends State<SwitcherContainer> {
  String name = '首页';
  List<String> nameList = ['首页', '书籍', '我的'];
  // 激活项
  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('导航'),
      ),
      body: Center(
        child: Text(name),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(label: '首页', icon: Icon(Icons.home)),
          BottomNavigationBarItem(label: '书籍', icon: Icon(Icons.book)),
          BottomNavigationBarItem(label: '我的', icon: Icon(Icons.perm_identity)),
        ],
        currentIndex: _currentIndex,
        // 激活颜色
        selectedItemColor: Colors.orange,
        //  点击事件
        onTap: (index) {
          setState(() {
            _currentIndex = index;
            name = nameList[index];
          });
        },
      ),
    );
  }
}

如果没有特殊需求的话,使用系统提供的就可以。如果想要点不太一样的可以看一下下面这两个库:

  • curved_navigation_bar
  • google_nav_bar

curved_navigation_bar

一个易于实现曲面导航条

官方地址
https://pub-web.flutter-io.cn/packages/curved_navigation_bar

安装

dart 复制代码
flutter pub add curved_navigation_bar

简单使用

dart 复制代码
class SwitcherContainerState extends State<SwitcherContainer> {
  String name = '首页';
  List<String> nameList = ['首页', '书籍', '我的'];
  // 激活项
  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('导航'),
      ),
      body: Stack(
        children: [
          Container(
            color: Colors.blueAccent,
            width: MediaQuery.of(context).size.width,
            height: MediaQuery.of(context).size.height,
            child: null,
          ),
          Container(
            color: Colors.white,
            width: MediaQuery.of(context).size.width,
            height: MediaQuery.of(context).size.height - 150,
            child: Text(name),
          )
        ],
      ),
      bottomNavigationBar: CurvedNavigationBar(
        items: const [
          Icon(Icons.home),
          Icon(Icons.book),
          Icon(Icons.perm_identity)
        ],
        height: 60,
        backgroundColor: Colors.blueAccent,
        //激活项
        index: _currentIndex,
        //  点击事件
        onTap: (index) {
          setState(() {
            _currentIndex = index;
            name = nameList[index];
          });
        },
      ),
    );
  }
}

这个最好像我上面那样再调整一下,不然有点奇怪,比如:

bottom_navy_bar

一个美丽而生动的底部导航。导航栏使用您当前的主题,但您可以自由自定义

官方地址
https://pub-web.flutter-io.cn/packages/bottom_navy_bar

安装

dart 复制代码
flutter pub add bottom_navy_bar

简单使用

dart 复制代码
class SwitcherContainerState extends State<SwitcherContainer> {
  String name = '首页';
  List<String> nameList = ['首页', '书籍', '我的'];
  // 激活项
  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('导航'),
      ),
      body: Center(
        child: Text(name),
      ),
      bottomNavigationBar: BottomNavyBar(
          //  当前选中项
          selectedIndex: _currentIndex,
          //  列表
          items: [
            BottomNavyBarItem(
                textAlign: TextAlign.center,
                icon: const Icon(Icons.home),
                title: const Text("首页")),
            BottomNavyBarItem(
                textAlign: TextAlign.center,
                icon: const Icon(Icons.book),
                title: const Text("书架")),
            BottomNavyBarItem(
                textAlign: TextAlign.center,
                icon: const Icon(Icons.perm_identity),
                title: const Text("我的"))
          ],
          //  选中事件
          onItemSelected: (index) => setState(() {
                _currentIndex = index;
                name = nameList[index];
              })),
    );
  }
}

TabBar

在Flutter中,TabBar是一个常用的小部件,用于创建一个具有选项卡的导航栏。它通常与TabBarView一起使用,以实现在不同选项卡之间切换内容的功能。

TabBarTabBarTabBarView两个关键组件组成。

TabBar:TabBar小部件定义了选项卡的外观和交互方式。它可以包含多个选项卡,每个选项卡都由一个Tab对象表示。可以通过设置controller属性来指定与TabBarView关联的TabController,以便在选项卡之间进行切换。

TabBarViewTabBarView``小部件是一个可滚动的容器,用于显示与当前选中选项卡相关联的内容。每个选项卡对应一个子小部件,并且可以通过设置controller属性来与TabBar`关联。

dart 复制代码
class SwitcherContainer extends StatefulWidget {
  const SwitcherContainer({Key? key}) : super(key: key);

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

class SwitcherContainerState extends State<SwitcherContainer>
    with SingleTickerProviderStateMixin {
  // 控制器
  late TabController tabController;

  @override
  void initState() {
    super.initState();
    tabController = TabController(length: 3, vsync: this);
  }

  @override
  void dispose() {
    super.dispose();
    //  释放
    tabController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('TabBar Demo'),
        bottom: TabBar( // 使用TabBar作为AppBar的bottom属性
          controller: tabController, // 关联TabController
          tabs: const [
            Tab(text: 'Tab 1'),
            Tab(text: 'Tab 2'),
            Tab(text: 'Tab 3'),
          ],
        ),
      ),
      body: TabBarView( // 使用TabBarView作为body
        controller: tabController, // 关联TabController
        children: const [
          Center(child: Text('Content of Tab 1')),
          Center(child: Text('Content of Tab 2')),
          Center(child: Text('Content of Tab 3')),
        ],
      ),
    );
  }
}

注意点:

  • 在Flutter中,TabBarTabBarView之间的切换通常需要使用动画效果。为了实现这种动画效果,需要使用TickerProvider,它提供了一个Ticker对象,用于生成动画的时间。而SingleTickerProviderStateMixin是一个实现了TickerProvider的混合类。

或者

dart 复制代码
return Column(
   children: [
     TabBar(
       controller: tabController,
       indicatorColor: Colors.red, // 设置选中选项卡下方的指示器颜色
       labelColor: Colors.blue, // 设置选中选项卡的文本颜色
       unselectedLabelColor: Colors.grey, // 设置未选中选项卡的文本颜色
       tabs: const [
         Tab(
           text: 'Home',
         ),
         Tab(
           text: 'Settings',
         ),
       ],
     ),
     Expanded(
       child: TabBarView(
         controller: tabController,
         children: const [
           Center(
             child: Text("Home"),
           ),
           Center(
             child: Text("Settings"),
           )
         ],
       ),
     ),
   ],
 );

这里推荐一下:tab_indicator_styler,这个库是用来修改指示器样式的

官方地址
https://pub-web.flutter-io.cn/packages/tab_indicator_styler

安装

dart 复制代码
flutter pub add tab_indicator_styler

基本使用

dart 复制代码
import 'package:tab_indicator_styler/tab_indicator_styler.dart';
dart 复制代码
Scaffold(
   appBar: AppBar(
     toolbarHeight: 10,
     bottom: TabBar(
       // 使用TabBar作为AppBar的bottom属性
       controller: tabController, // 关联TabController
       indicatorSize: TabBarIndicatorSize.tab,  // 设置指示器宽度
       // 指示器样式
       indicator: MaterialIndicator(
         height: 5,
         topLeftRadius: 8,
         topRightRadius: 8,
         horizontalPadding: 50,
         tabPosition: TabPosition.bottom,
         color: Colors.white
       ),
       tabs: const [
         Tab(text: 'Tab 1'),
         Tab(text: 'Tab 2'),
         Tab(text: 'Tab 3'),
       ],
     ),
   ),
   body: TabBarView(
     // 使用TabBarView作为body
     controller: tabController, // 关联TabController
     children: const [
       Center(child: Text('Content of Tab 1')),
       Center(child: Text('Content of Tab 2')),
       Center(child: Text('Content of Tab 3')),
     ],
   ),
 );

注意:MaterialIndicator风格的指示器的宽度必须使用indicatorSize: TabBarIndicatorSize.tab,也就是默认值,否则会报错

dart 复制代码
indicator: DotIndicator(
       radius: 5,
       color: Colors.orange,
       //  圆点距离文字的间距,正数在下面,负数在上面
       distanceFromCenter: 20,
     ),
dart 复制代码
indicator: RectangularIndicator(
      bottomLeftRadius: 30,
      bottomRightRadius: 30,
      topLeftRadius: 30,
      topRightRadius: 30,
    ),
相关推荐
孤鸿玉16 小时前
Fluter InteractiveViewer 与ScrollView滑动冲突问题解决
flutter
叽哥1 天前
Flutter Riverpod上手指南
android·flutter·ios
BG2 天前
Flutter 简仿Excel表格组件介绍
flutter
zhangmeng2 天前
FlutterBoost在iOS26真机运行崩溃问题
flutter·app·swift
恋猫de小郭2 天前
对于普通程序员来说 AI 是什么?AI 究竟用的是什么?
前端·flutter·ai编程
卡尔特斯2 天前
Flutter A GlobalKey was used multipletimes inside one widget'schild list.The ...
flutter
w_y_fan2 天前
Flutter 滚动组件总结
前端·flutter
醉过才知酒浓2 天前
Flutter Getx 的页面传参
flutter
火柴就是我3 天前
flutter 之真手势冲突处理
android·flutter
Speed1233 天前
`mockito` 的核心“打桩”规则
flutter·dart