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,
    ),
相关推荐
ak啊1 小时前
Dart 基础教程
flutter·dart
早起的年轻人1 小时前
Flutter中如何判断一个计算任务是否耗时?
flutter
pengyu2 小时前
【Flutter 状态管理 - 四】 | setState的工作机制探秘
android·flutter·dart
环信即时通讯云3 小时前
实战|使用环信Flutter SDK构建鸿蒙HarmonyOS应用及推送配置
flutter·华为·harmonyos
亚洲小炫风6 小时前
Melos 发布pub.dev
flutter·pub.dev
东东爱编码6 小时前
一路磕磕绊绊解决flutter doctor 报错CocoaPods not installed
flutter·xcode·cocoapods
louisgeek8 小时前
Flutter 简介
flutter
JarvanMo19 小时前
关于Flutter架构的小小探讨
前端·flutter
顾林海19 小时前
Flutter 图标和按钮组件
android·开发语言·前端·flutter·面试