Flutter 底部导航栏BottomNavigationBar,并关联PageView实现滑动切换

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yechaoa/article/details/89880284

效果图:
在这里插入图片描述

BottomNavigationBar

先来看一下官方的sample code:

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  int _selectedIndex = 1;
  final _widgetOptions = [
    Text('Index 0: Home'),
    Text('Index 1: Business'),
    Text('Index 2: School'),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('BottomNavigationBar Sample'),
      ),
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
          BottomNavigationBarItem(icon: Icon(Icons.business), title: Text('Business')),
          BottomNavigationBarItem(icon: Icon(Icons.school), title: Text('School')),
        ],
        currentIndex: _selectedIndex,
        fixedColor: Colors.deepPurple,
        onTap: _onItemTapped,
      ),
    );
  }

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }
}

在_MyHomePageState 类中,先是定义了一个int下标,然后是一个Text数组,
然后就是页面,分为3部分:

  • appBar,即标题
  • body,内容显示区域
  • bottomNavigationBar,底部导航栏

bottomNavigationBar中的一些参数:

  • items,即导航栏中的小tab
  • currentIndex,选中的下标
  • fixedColor,选中的颜色
  • onTap,即item的click事件

items超过3个显示白色,加一个参数即可:type: BottomNavigationBarType.fixed,

在_onItemTapped方法中,可以把传入的下标赋值给定义好的_selectedIndex ,再用setState包裹起来就可以实现状态更新、内容切换了。

demo中切换的只是Text而已,那如果要切换页面怎么做呢


切换页面

切换Text与切换页面原理也是相通的

  • 也定义一个页面的数组
  var pages = <Widget>[
    HomePage(),
    TreePage(),
    NaviPage(),
    ProjectPage(),
  ];
  • 把body换成页面
      body: Center(
        child: pages.elementAt(_selectedIndex),
      ),

ok,就是这么简单。

那如果除了点击切换以外,我能不能滑动切换呢,也是可以的


滑动切换

要实现滑动切换,我们需要把body换成PageView

      body: new PageView.builder(
        onPageChanged: _pageChange,
        controller: _pageController,
        itemCount: pages.length,
        itemBuilder: (BuildContext context, int index) {
          return pages.elementAt(_selectedIndex);
        },
      ),
  • onPageChanged,页面改变监听
  • controller,页面控制器
  • itemCount,即页面数量
  • itemBuilder,页面加载器

onPageChanged:

void _pageChange(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

然后修改_onItemTapped方法:

用_pageController去控制页面的显示

  void _onItemTapped(int index) {
    //bottomNavigationBar 和 PageView 关联
    _pageController.animateToPage(index,duration: const Duration(milliseconds: 300), curve: Curves.ease);
  }

ok,已经完成了。


完整代码

main.dart:

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: YStrings.appName,
      theme: ThemeData(
        // This is the theme of your application.

//        primarySwatch: Colors.blue,
        primaryColor: YColors.colorPrimary,
        primaryColorDark: YColors.colorPrimaryDark,
        accentColor: YColors.colorAccent,
        dividerColor: YColors.dividerColor,
      ),
      home: MyHomePage(title: YStrings.appName),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _selectedIndex = 0;

  var _pageController = new PageController(initialPage: 0);

  var pages = <Widget>[
    HomePage(),
    TreePage(),
    NaviPage(),
    ProjectPage(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(YStrings.appName),
      ),
//      body: Center(
//        child: pages.elementAt(_selectedIndex),
//      ),
      body: new PageView.builder(
        onPageChanged: _pageChange,
        controller: _pageController,
        itemCount: pages.length,
        itemBuilder: (BuildContext context, int index) {
          return pages.elementAt(_selectedIndex);
        },
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text(YStrings.home)),
          BottomNavigationBarItem(icon: Icon(Icons.filter_list), title: Text(YStrings.tree)),
          BottomNavigationBarItem(icon: Icon(Icons.low_priority), title: Text(YStrings.navi)),
          BottomNavigationBarItem(icon: Icon(Icons.apps), title: Text(YStrings.project)),
        ],
        currentIndex: _selectedIndex,//当前选中下标
        type: BottomNavigationBarType.fixed,//显示模式
        fixedColor: YColors.colorPrimary,//选中颜色
        onTap: _onItemTapped, //点击事件
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: showToast,
        tooltip: '点击选中最后一个',
        child: Icon(Icons.add,color: Colors.white),
      ),
    );
  }

  void _onItemTapped(int index) {
    //bottomNavigationBar 和 PageView 关联
    _pageController.animateToPage(index,duration: const Duration(milliseconds: 300), curve: Curves.ease);
  }

  void _pageChange(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  void showToast() {
    Fluttertoast.showToast(
        msg: "选中最后一个",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
        timeInSecForIos: 1,
        backgroundColor: YColors.colorPrimaryDark,
        textColor: Colors.white,
        fontSize: 16.0);
    print("---click---");
    _onItemTapped(3);
  }
}

homePage.dart(别的page也没差)

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Center(
      child: new Text(YStrings.home,
          style: TextStyle(fontSize: 50, color: Colors.red)),
    );
  }
}

官方文档:https://docs.flutter.io/flutter/material/BottomNavigationBar-class.html


猜你喜欢

转载自blog.csdn.net/yechaoa/article/details/89880284