Flutter布局-底部导航栏实现

手写实现

  • 没有过渡动画,也没有保存状态
import 'package:flutter/material.dart'; import 'tabbar/First.dart'; import 'tabbar/Second.dart'; import 'tabbar/Third.dart'; class TabbarPage extends StatefulWidget { TabbarPage({Key key}) : super(key: key); @override _TabbarPageState createState() => _TabbarPageState(); } class _TabbarPageState extends State<TabbarPage> { int _currentIndex = 0; List<Widget> _pageList = [ FirstPage(), SecondPage(), ThirdPage() ]; @override Widget build(BuildContext context) { return Scaffold( body: this._pageList[this._currentIndex], bottomNavigationBar: BottomNavigationBar( currentIndex: this._currentIndex, onTap: (index) { setState(() { this._currentIndex = index; }); }, type: BottomNavigationBarType.fixed, fixedColor: Colors.red, items: [ BottomNavigationBarItem(title: Text('首页'), icon: Icon(Icons.home)), BottomNavigationBarItem(title: Text('分类'), icon: Icon(Icons.category)), BottomNavigationBarItem(title: Text('我的'), icon: Icon(Icons.people)), ] ), ); } }

IndexdStack

  • 没有过渡动画,保持所有的页面状态
import 'package:flutter/material.dart'; import 'tabbar/First.dart'; import 'tabbar/Second.dart'; import 'tabbar/Third.dart'; class TabbarPage extends StatefulWidget { TabbarPage({Key key}) : super(key: key); @override _TabbarPageState createState() => _TabbarPageState(); } class _TabbarPageState extends State<TabbarPage> { int _currentIndex = 0; List<Widget> _pageList = [ FirstPage(), SecondPage(), ThirdPage() ]; @override Widget build(BuildContext context) { return Scaffold( body: IndexedStack( index: this._currentIndex, children: this._pageList, ), bottomNavigationBar: BottomNavigationBar( currentIndex: this._currentIndex, onTap: (index) { setState(() { this._currentIndex = index; }); }, type: BottomNavigationBarType.fixed, fixedColor: Colors.red, items: [ BottomNavigationBarItem(title: Text('首页'), icon: Icon(Icons.home)), BottomNavigationBarItem(title: Text('分类'), icon: Icon(Icons.category)), BottomNavigationBarItem(title: Text('我的'), icon: Icon(Icons.people)), ] ), ); } }

PageView

  • 使用this._pageController.jumpToPage(this._currentIndex);跳转

  • 可以左右滑动切换,如果不需要此功能,可以禁用physics: NeverScrollableScrollPhysics(),

import 'package:flutter/material.dart'; import 'tabbar/First.dart'; import 'tabbar/Second.dart'; import 'tabbar/Third.dart'; class TabbarPage extends StatefulWidget { TabbarPage({Key key}) : super(key: key); @override _TabbarPageState createState() => _TabbarPageState(); } class _TabbarPageState extends State<TabbarPage> { int _currentIndex = 0; List<Widget> _pageList = [ FirstPage(), SecondPage(), ThirdPage() ]; PageController _controller = new PageController(initialPage: 0); @override Widget build(BuildContext context) { return Scaffold( body: PageView( controller: this._controller, children: this._pageList, onPageChanged: (index) { setState(() { // 左右滑动的时候,需要手动置 this._currentIndex this._currentIndex = index; }); }, // 禁止pageview滑动 // physics: NeverScrollableScrollPhysics(), ), bottomNavigationBar: BottomNavigationBar( currentIndex: this._currentIndex, onTap: (index) { setState(() { this._currentIndex = index; this._controller.jumpToPage(index); }); }, type: BottomNavigationBarType.fixed, fixedColor: Colors.red, items: [ BottomNavigationBarItem(title: Text('首页'), icon: Icon(Icons.home)), BottomNavigationBarItem(title: Text('分类'), icon: Icon(Icons.category)), BottomNavigationBarItem(title: Text('我的'), icon: Icon(Icons.people)), ] ), ); } }
  • 可以保持部分页面的状态,比如保持SecondPage页面状态,需要修改tabbar/Second.dart。添加with AutomaticKeepAliveClientMixinwantKeepAlive
import 'package:flutter/material.dart'; class SecondPage extends StatefulWidget { SecondPage({Key key}) : super(key: key); @override _SecondPageState createState() => _SecondPageState(); } class _SecondPageState extends State<SecondPage> with AutomaticKeepAliveClientMixin { @override bool get wantKeepAlive => true; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('second page'), ), body: Center( child: Text('second page'), ), ); } }

TabBar + TabBarView

  • 使用indicator: BoxDecoration()取消掉每个tab下面的横线

  • 可以左右滑动切换,如果不需要此功能,可以禁用physics: NeverScrollableScrollPhysics(),

import 'package:flutter/material.dart'; import 'tabbar/First.dart'; import 'tabbar/Second.dart'; import 'tabbar/Third.dart'; class TabbarPage extends StatefulWidget { TabbarPage({Key key}) : super(key: key); @override _TabbarPageState createState() => _TabbarPageState(); } class _TabbarPageState extends State<TabbarPage> with SingleTickerProviderStateMixin { List<Widget> _pageList = [ FirstPage(), SecondPage(), ThirdPage() ]; TabController _controller; @override void initState() { super.initState(); this._controller = new TabController(length: 3, vsync: this); } @override Widget build(BuildContext context) { return Scaffold( body: TabBarView( controller: this._controller, children: this._pageList, // 禁止TabBarView滑动 // physics: NeverScrollableScrollPhysics(), ), bottomNavigationBar: TabBar( // 取消下面的横线 indicator: BoxDecoration(), labelColor: Colors.red, unselectedLabelColor: Colors.grey, controller: this._controller, tabs: <Widget>[ Tab(text: '首页', icon: Icon(Icons.home),), Tab(text: '分类', icon: Icon(Icons.category),), Tab(text: '我的', icon: Icon(Icons.people),), ], ), ); } }

创作不易,若本文对你有帮助,欢迎打赏支持作者!

 分享给好友: