Flutter搭建一个基本的app架构,tabBar + navgationBar + views
1.首先理清思路,创建tabBar -> 选中第一个标签 -> 进入第一个子页面 -> 创建nagationBar -> 创建顶部分页tab
2. 创建tabBar,找到main函数入口,创建一个类命名为自定义的tabBarController,将它作为函数的返回值。
void main () => runApp(LiveApp()); class LiveApp extends StatelessWidget { @override Widget build(BuildContext context) { return CYTabBarController(); } }大概就是这样,这样我们就创建好了一个入口。
2.来到这个新建的文件,实现一个Widget MaterialApp里面的属性主要使用home:Widget。
class CYTabBarController extends StatefulWidget { @override _CYTabBarControllerState createState() => _CYTabBarControllerState(); } class _CYTabBarControllerState extends State<CYTabBarController> { @override @override Widget build(BuildContext context) { return MaterialApp( home: , ); } }接下来就是要给这个home一个函数返回值为Widget或者直接赋值Widget。
这里给一个Scaffold Widget,Scaffold 的主要用到的有appBar,body,title,bottomNavigationBar,
appBar 就是导航栏,title等价于导航栏上的居中的view,你可以自定一个Widget赋值给它,body是你需要显示的内容,bottomNavigationBar就是底部的tabBar了。
3.实现tabBar
一种做法是用tabBarView,这样效果就是可以左右滚动,需要创建一个TabController,它是负责管理tabView的。
另一种做法就是用bottomNavigationBar,这个是不可以滚动的,也不需要TabController去管理。
这里我选择用bottomNavigationBar去做,具体做法看个人的喜好。
BottomNavigationBar 需要实现一个items,就是BottomNavigationBarItem的数组,有多少了tab标签就创建多少个。
items: [BottomNavigationBarItem(icon: Icon(Icons.home),title: Text('首页')), BottomNavigationBarItem(icon: Icon(Icons.live_tv),title: Text('直播')), BottomNavigationBarItem(icon: Icon(Icons.find_in_page),title: Text('发现')), BottomNavigationBarItem(icon: Icon(Icons.my_location),title: Text('我的')),],这里我创建了4个item。
看一下源码,需要哪些参数和可以设置哪些参数
BottomNavigationBar({ Key key, @required this.items, this.onTap, this.currentIndex = 0, this.elevation = 8.0, BottomNavigationBarType type, Color fixedColor, this.backgroundColor, this.iconSize = 24.0, Color selectedItemColor, this.unselectedItemColor, this.selectedIconTheme = const IconThemeData(), this.unselectedIconTheme = const IconThemeData(), this.selectedFontSize = 14.0, this.unselectedFontSize = 12.0, this.selectedLabelStyle, this.unselectedLabelStyle, this.showSelectedLabels = true, bool showUnselectedLabels, })这些都是常用的可设置,@required 是必须赋值的,具体用法看字面意思就知道了,这里不去介绍。
来看看具体的实现
bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, items: [BottomNavigationBarItem(icon: Icon(Icons.home),title: Text('首页')), BottomNavigationBarItem(icon: Icon(Icons.live_tv),title: Text('直播')), BottomNavigationBarItem(icon: Icon(Icons.find_in_page),title: Text('发现')), BottomNavigationBarItem(icon: Icon(Icons.my_location),title: Text('我的')),], currentIndex: currentIndex, selectedFontSize: 13, unselectedFontSize: 13, selectedItemColor: Colors.green, onTap: (index) { setState(() { currentIndex = index; }); }, )有一个index很重要,就是你点击返回给你的按钮下标,通过StatefulWidget 的setState 可以监听它的改变然后做出相应的调整。
4.创建一个IndexedStack的Widget,它有一个children和index属性,我们将需要显示的界面先创建好导入,然后放入children里面,index赋值当前选中的下标,这样做的好处是不用每次都去渲染。
Widget build(BuildContext context) { return MaterialApp( home: Scaffold( bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, items: [BottomNavigationBarItem(icon: Icon(Icons.home),title: Text('首页')), BottomNavigationBarItem(icon: Icon(Icons.live_tv),title: Text('直播')), BottomNavigationBarItem(icon: Icon(Icons.find_in_page),title: Text('发现')), BottomNavigationBarItem(icon: Icon(Icons.my_location),title: Text('我的')),], currentIndex: currentIndex, selectedFontSize: 13, unselectedFontSize: 13, selectedItemColor: Colors.green, onTap: (index) { setState(() { currentIndex = index; }); }, ), body: IndexedStack( children: <Widget>[ HomeView(), LiveView(), DiscoverView(), MyZoneView(), ], index: currentIndex, ), ), ); }看看具体的效果
5.创建一个滑动的tab分页。
来到首页你创建的类里面,大概是这样
class HomeView extends StatefulWidget { @override _HomeViewState createState() => _HomeViewState(); } class _HomeViewState extends State<HomeView> { @override Widget build(BuildContext context) { return Container( child: Center( child: Text('首页',style: TextStyle(fontSize: 18)), ), ); } }这里需要用到的Widget主要有Scaffold,TabBar,TabBarView,用到了tabBar和TabBarView首先就要创建一个TabController,
用来管理它们。
这里要用到一个initState()和dispose()函数,一个用来创建,一个用来销毁。
在initState()函数里面将TabController 创建好。
void initState() { // TODO: implement initState tabController = TabController( length: 3, vsync: this, ); super.initState(); }length是需要管理的tab数组长度,vsync就简单理解为发送一个同步信号,这里要渲染了。
对应的dispose()里面
@override void dispose() { // TODO: implement dispose tabController.dispose(); super.dispose(); }创建的步骤和上面类似,如下
@override Widget build(BuildContext context) { super.build(context); return Scaffold( appBar: AppBar( backgroundColor: Colors.green, title: Text('首页',style: TextStyle(fontSize: 22),), bottom: TabBar( indicatorColor: Colors.white, indicatorSize: TabBarIndicatorSize.label, unselectedLabelStyle: TextStyle( fontSize: 15, fontWeight: FontWeight.w500, ), unselectedLabelColor: Colors.white54, labelColor: Colors.white, labelStyle: TextStyle( fontSize: 20, fontWeight: FontWeight.w500 ), controller: tabController, tabs: <Widget>[ Tab(text: '电影',), Tab(text: '读书',), Tab(text: '新闻',), ], ), ), body: TabBarView( controller: tabController, children: <Widget>[ MoviesView(), BooksView(), NewsView(), ], ), ); }这样就创建好了一个分页滑动的tab。
demo下载地址:Flutter创建tabbar