前言
Home页面是通过BottomNavigationBar去进行切换的,当BottomNavigationBar选中第一个的时候则会打开我们的Home页面
Home页面

创建Home页面
首先需要创建Home页面在BottomNavigationBar切换到第一个的时候展示,而且在实际使用中,我们不希望每次切换到HomePage都创建一个新的,而是需要它持久化,所以我们的Body部分需要使用到PageView
创建一个空的HomePage
class HomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return HomePageState();
}
}
class HomePageState extends State with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return Text('Home');
}
}
修改下之前创好的Mainpage
class MainPage extends StatefulWidget {
final String title;
@override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
int currentIndex = 0;
var _pageController = PageController();
var pages = <Widget>[
HomePage(),
Text('1'),
Text('2'),
Text('3'),
Text('4'),
];
void onNavigationChanged(int index) {
setState(() {
currentIndex = index;
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
body: PageView.builder(
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) => pages[index],
controller: _pageController,
itemCount: pages.length,
onPageChanged: onNavigationChanged,
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
BottomNavigationBarItem(icon: Icon(Icons.book), label: '书影音'),
BottomNavigationBarItem(icon: Icon(Icons.group), label: '小组'),
BottomNavigationBarItem(icon: Icon(Icons.store), label: '市集'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: '我')
],
currentIndex: currentIndex,
unselectedItemColor: Colors.grey,
selectedItemColor: Colors.green,
type: BottomNavigationBarType.fixed,
onTap: (index){
_pageController.jumpToPage(index);
},
),
);
}
}
其中currentIndex表示BottomNavigationBar当前切换到位置的一个状态
使用PageView.builder去构建一个PageView
physics: NeverScrollableScrollPhysics()表示不允许左右滑动
itemBuilder表示当前PageView需要根据Index显示什么内容,这里的index指的是PageView的
itemCount表示页面的数量
onPageChanged 表示当页面改变的时候会回调的函数,我们设置了不能滑动,所以页面切换只能是手动的
BottomNavigationBar中的onTap我们通过PageController手动切换了PageView的页面
此时当BottomNavigationBar默认选中第一个的时候就会打开HomePage(),并且重复切换不会创建新的HomePage实例,这样就可以保存HomePage的状态
HomePage
AppBar
顶部是使用AppBar构成的,并且可以左右切换的动态,推荐也是AppBar的一部分,所以我们首先需要对AppBar进设置
class HomePageState extends State with SingleTickerProviderStateMixin,AutomaticKeepAliveClientMixin {
TabController? _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
}
@override
void dispose() {
_tabController?.dispose();
super.dispose();
}
AppBar homePageAppBar() {
return AppBar(
backgroundColor: Colors.white,
elevation: 1,
leading: Icon(Icons.menu, color: Colors.green),
actions: [
Container(
alignment: Alignment.center,
child: Icon(Icons.mail_outline, color: Colors.green),
padding: EdgeInsets.only(left: 16, right: 16),
)
],
centerTitle: true,
titleSpacing: 0,
title: GestureDetector(
child: Container(
height: 35,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: Color(0x12000000)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.search,
color: Colors.black26,
),
Text('绝命律师 第六季',
style: TextStyle(color: Colors.black26, fontSize: 15))
],
),
),
onTap: () => {},
),
bottom: PreferredSize(
preferredSize: const Size.fromHeight(45),
child: Container(
alignment: Alignment.centerLeft,
child: TabBar(
isScrollable: true,
controller: _tabController,
labelColor: Colors.black,
indicatorColor: Colors.black,
indicatorSize: TabBarIndicatorSize.label,
labelStyle:
TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
unselectedLabelStyle:
TextStyle(fontSize: 20, fontWeight: FontWeight.normal),
labelPadding: EdgeInsets.only(left: 20, right: 20),
tabs: [Tab(text: '动态'), Tab(text: '推荐')],
))));
}
@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
appBar: homePageAppBar(),
body: TabBarView(
children: [Tab(text: '动态'), Tab(text: '推荐')],
controller: _tabController,
));
}
@override
bool get wantKeepAlive => true;
}
homePageAppBar函数是用来返回一个AppBar的对象,分别设置了这些主要属性
backgroundColor 背景颜色
elevation 阴影高度
leading 左边widget
actions 右边的widget
titleSpacing title左右的距离
centerTitle title是否居中
title title的widget
还有一个比较重要的bottm属性是用来设置TabBar的样式,我们一般也可以直接返回一个TabBar默认是直接横向撑开并且居中的,但是由于我们的TabBar是一个居左的样式所以做了个限定
Body
Body部分就属于TabBar的切换内容,所以在body部分直接使用了可以合TabBar联动的TabBarView即可,他们使用一个相同的Controller
欢迎关注Mike的简书
Android 知识整理