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