Flutter 底部导航 tabs bar的实现详解

66 min read

Flutter 提供了一种可定制的底部导航栏控件 BottomNavigationBar,可以让我们轻松地在应用程序的底部显示导航选项卡。

底部导航栏在移动应用程序中非常常见,通常用于导航应用程序的不同页面、历史记录或功能。

下面是一些实现底部导航栏的详细步骤:

第一步:在 main.dart 文件中导入相关的库

import 'package:flutter/material.dart';

第二步:在 main.dart 文件的 MyApp 类中添加一个底部导航栏

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter BottomNavigationBar Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter BottomNavigationBar Example'),
        ),
        body: Center(
          child: Text('Hello World'),
        ),
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: 0, // 设置默认选中项的下标
          onTap: (int index) {}, // 点击事件回调函数
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.search),
              label: 'Search',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.person),
              label: 'Profile',
            ),
          ],
        ),
      ),
    );
  }
}

底部导航栏需要设置三个属性:

  • currentIndex:默认选中项的下标。可以使用 onTap 回调函数修改该值,以便在导航栏上切换选项卡。
  • onTap:底部导航栏项被点击时的回调函数,它会接收一个 int 类型的参数,表示被点击的项的下标。
  • items:一个包含 BottomNavigationBarItem 对象的列表。每一个 BottomNavigationBarItem 对象都表示导航栏的一个选项卡,需要设置 iconlabel 两个属性。

第三步:添加导航栏项的页面

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('Home Page'),
      ),
    );
  }
}

class SearchPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('Search Page'),
      ),
    );
  }
}

class ProfilePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('Profile Page'),
      ),
    );
  }
}

第四步:在 main.dart 文件中使用 IndexedStack 组件实现页面切换

我们使用 IndexedStack 组件将页面组合在一起,并使用底部导航栏的 onTap 回调函数切换当前显示的页面。

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

class _MyAppState extends State<MyApp> {
  int _currentIndex = 0;
  final List<Widget> _children = [
    HomePage(),
    SearchPage(),
    ProfilePage(),
  ];

  void _onTap(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter BottomNavigationBar Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter BottomNavigationBar Example'),
        ),
        body: IndexedStack(
          index: _currentIndex,
          children: _children,
        ),
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: _currentIndex,
          onTap: _onTap,
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.search),
              label: 'Search',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.person),
              label: 'Profile',
            ),
          ],
        ),
      ),
    );
  }
}

Scaffold 组件的 body 中使用 IndexedStack 组件包裹住三个页面,并使用 _currentIndex 变量来指示当前显示的页面。

当底部导航栏的项被点击时,使用 setState() 方法更新 _currentIndex 变量的值,并重新构建界面以反映新的状态。