前言
Home
頁面是通過BottomNavigationBar
去進(jìn)行切換的宿稀,當(dāng)BottomNavigationBar
選中第一個(gè)的時(shí)候則會(huì)打開我們的Home
頁面
Home頁面
創(chuàng)建Home頁面
首先需要?jiǎng)?chuàng)建Home
頁面在BottomNavigationBar
切換到第一個(gè)的時(shí)候展示哈垢,而且在實(shí)際使用中,我們不希望每次切換到HomePage
都創(chuàng)建一個(gè)新的惫霸,而是需要它持久化猫缭,所以我們的Body
部分需要使用到PageView
創(chuàng)建一個(gè)空的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');
}
}
修改下之前創(chuàng)好的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
當(dāng)前切換到位置的一個(gè)狀態(tài)
使用PageView.builder
去構(gòu)建一個(gè)PageView
physics: NeverScrollableScrollPhysics()
表示不允許左右滑動(dòng)
itemBuilder
表示當(dāng)前PageView
需要根據(jù)Index
顯示什么內(nèi)容,這里的index
指的是PageView
的
itemCount
表示頁面的數(shù)量
onPageChanged
表示當(dāng)頁面改變的時(shí)候會(huì)回調(diào)的函數(shù)壹店,我們?cè)O(shè)置了不能滑動(dòng)猜丹,所以頁面切換只能是手動(dòng)的
BottomNavigationBar
中的onTap
我們通過PageController
手動(dòng)切換了PageView
的頁面
此時(shí)當(dāng)BottomNavigationBar
默認(rèn)選中第一個(gè)的時(shí)候就會(huì)打開HomePage()
,并且重復(fù)切換不會(huì)創(chuàng)建新的HomePage
實(shí)例硅卢,這樣就可以保存HomePage
的狀態(tài)
HomePage
AppBar
頂部是使用AppBar構(gòu)成的射窒,并且可以左右切換的動(dòng)態(tài),推薦
也是AppBar的一部分将塑,所以我們首先需要對(duì)AppBar
進(jìn)設(shè)置
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: '動(dòng)態(tài)'), Tab(text: '推薦')],
))));
}
@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
appBar: homePageAppBar(),
body: TabBarView(
children: [Tab(text: '動(dòng)態(tài)'), Tab(text: '推薦')],
controller: _tabController,
));
}
@override
bool get wantKeepAlive => true;
}
homePageAppBar
函數(shù)是用來返回一個(gè)AppBar
的對(duì)象,分別設(shè)置了這些主要屬性
backgroundColor
背景顏色
elevation
陰影高度
leading
左邊widget
actions
右邊的widget
titleSpacing
title左右的距離
centerTitle
title是否居中
title
title的widget
還有一個(gè)比較重要的bottm
屬性是用來設(shè)置TabBar的樣式脉顿,我們一般也可以直接返回一個(gè)TabBar
默認(rèn)是直接橫向撐開并且居中的,但是由于我們的TabBar
是一個(gè)居左的樣式所以做了個(gè)限定
Body
Body
部分就屬于TabBar
的切換內(nèi)容点寥,所以在body
部分直接使用了可以合TabBar
聯(lián)動(dòng)的TabBarView
即可艾疟,他們使用一個(gè)相同的Controller
歡迎關(guān)注Mike的簡(jiǎn)書
Android 知識(shí)整理