
鎮(zhèn)樓美女
前面一節(jié)已經(jīng)介紹完了閃屏廣告頁,那么今天要實(shí)現(xiàn)的就是
HomePage界面,先來看看home界面長啥樣?如下圖所示:
home界面
- 底部是一個(gè)bottomNavigationBar,放置五個(gè)分類導(dǎo)航按鈕,分別對(duì)應(yīng)五個(gè)不同功能頁面;
- 除去底部導(dǎo)航區(qū)之外是個(gè)內(nèi)容展示區(qū),當(dāng)點(diǎn)擊底部不同的導(dǎo)航按鈕時(shí),該區(qū)域顯示不同的內(nèi)容,類似于Android原生開發(fā)的FrameLayout布局。
接下來就一步步實(shí)現(xiàn)這個(gè)homePage頁面
在lib\page目錄下新建一個(gè)home_page.dart文件,添加如下內(nèi)容:
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with AutomaticKeepAliveClientMixin {
//添加AutomaticKeepAliveClientMixin,
//并實(shí)現(xiàn)對(duì)應(yīng)的方法bool get wantKeepAlive => true;
//同時(shí)build方法實(shí)現(xiàn)父方法 super.build(context);
@override
Widget build(BuildContext context) {
super.build(context);
// 方式一:默認(rèn)設(shè)置寬度1080px,高度1920px
ScreenUtil.init(context);
// 方式二:設(shè)置寬度750px,高度1334px
// ScreenUtil.init(context, width: 750, height: 1334);
// 方式三:設(shè)置寬度750px,高度1334px,根據(jù)系統(tǒng)字體進(jìn)行縮放
// ScreenUtil.init(context, width: 1080, height: 1920, allowFontScaling: true);
return Scaffold(
body: null,
bottomNavigationBar: BottomNavigationBar(
items: null,
onTap: _onTapHandler,
currentIndex: 0,
type: BottomNavigationBarType.fixed,
fixedColor: Colors.red,
unselectedItemColor: Colors.black87,
backgroundColor: Colors.white,
),
);
}
}
上面的代碼只是一個(gè)大概的框架。
- 首先在引入
AutomaticKeepAliveClientMixin,這樣當(dāng)點(diǎn)擊底部導(dǎo)航按鈕切換的時(shí)候再切換回之前的頁面仍能保持頁面跳轉(zhuǎn)之前的瀏覽位置,比如說在第一個(gè)導(dǎo)航按鈕頁面瀏覽到中間的位置點(diǎn)擊了第二個(gè)導(dǎo)航按鈕切換到新頁面然后又點(diǎn)擊第一個(gè)導(dǎo)航按鈕切換回第一個(gè)頁面,這時(shí)如果不混入AutomaticKeepAliveClientMixin則第一個(gè)頁面就會(huì)重新加載,所有數(shù)據(jù)都會(huì)恢復(fù)初始狀態(tài),但是現(xiàn)在加入了這句AutomaticKeepAliveClientMixin就能保持之前的頁面瀏覽狀態(tài)而不重新加載?;烊脒@個(gè)之后要重寫其wantKeepAlive屬性,只要返回一個(gè)true即可。
@override
bool get wantKeepAlive => true;
- 同時(shí)引入第三方的屏幕適配插件
flutter_screenutil: ^1.1.0,并在build方法下進(jìn)行初始化ScreenUtil.init(context),整個(gè)App的設(shè)計(jì)稿尺寸按默認(rèn)尺寸配置(1920*1080)。 - 添加底部導(dǎo)航按鈕對(duì)應(yīng)的
page頁面,在lib\page目錄下新建五個(gè)頁面,分別命名為food_set_page.dart、food_show_page.dart、food_reviews_page.dart、heath_eat_page.dart及my_page.dart,然后在build方法中添加如下代碼:
//底部需要切換的頁面
final List<Widget> _pages = [
FoodSetPage(),
FoodShowPage(),
FoodReviewsPage(),
HeathEatPage(),
MyPage(),
];
- 底部的導(dǎo)航區(qū)采用的是
BottomNavigationBar,其構(gòu)造方法如下,
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,
})
參數(shù)說明:
| 屬性 | 說明 |
|---|---|
| type | 風(fēng)格BottomNavigationBarType.fixed(超過4個(gè)按鍵一定要加這個(gè),說明是多個(gè)按鈕)BottomNavigationBarType.shifting |
| items | List<BottomNavigationBarItem>[] 底部導(dǎo)航條按鈕集合 |
| onTap | 選中變化回調(diào)函數(shù) |
| currentIndex | 索引值,默認(rèn)0 默認(rèn)選中第幾個(gè) |
| elevation | 默認(rèn)8 |
| iconSize | 圖片大小 |
| BottomNavigationBarType.fixed | 風(fēng)格屬性 |
| fixedColor | 選中的顏色 |
| backgroundColor | 背景顏色 |
| BottomNavigationBarType.shifting | 風(fēng)格屬性 |
| selectedItemColor | 選中時(shí)顏色 |
| unselectedItemColor | 未選中時(shí)顏色 |
| selectedIconTheme | 選中時(shí)Icon的主題 |
| unselectedIconTheme | 未選中時(shí)Icon的主題 |
| selectedFontSize | 默認(rèn)14 |
| unselectedFontSize | 默認(rèn)12 |
| selectedLabelStyle | 選中時(shí)Label的樣式 |
| unselectedLabelStyle | 未選中時(shí)Label的樣式 |
| showSelectedLabels | 默認(rèn)true |
| showUnselectedLabels | 未選中時(shí)的Label |
從上面看出,items 是必填的屬性參數(shù),也就是一個(gè) BottomNavigationBarItem Widget列表。
每個(gè)按鈕對(duì)應(yīng)一個(gè)BottomNavigationBarItem,其構(gòu)造函數(shù)如下
const BottomNavigationBarItem({
@required this.icon,
this.title,
Widget activeIcon,
this.backgroundColor,
}) : activeIcon = activeIcon ?? icon,
assert(icon != null);
參數(shù)說明:
| 屬性 | 說明 |
|---|---|
| icon | 圖標(biāo) |
| title | 文字 |
| activeIcon | 選中后的圖標(biāo) |
| backgroundColor | 背景色 |
icon 和 activeIcon 是兩個(gè)狀態(tài)下的圖標(biāo),title 則是文本,只有默認(rèn)的 icon 是必須的。用一個(gè)List來存放底部的導(dǎo)航item
//底部導(dǎo)航item的文字和圖片
final List<BottomNavigationBarItem> tabs = [
BottomNavigationBarItem(
icon: Icon(FontAwesome.home),
title: Text('食集'),
),
BottomNavigationBarItem(
icon: Icon(FontAwesome.gift),
title: Text('食秀'),
),
BottomNavigationBarItem(
icon: Icon(FontAwesome.smile_o),
title: Text('食記'),
),
BottomNavigationBarItem(
icon: Icon(FontAwesome.question_circle_o),
title: Text('吃什么'),
),
BottomNavigationBarItem(
icon: Icon(FontAwesome.github),
title: Text('我的'),
),
];
然后在build方法下的Scaffold中設(shè)置bottomNavigationBar的相關(guān)屬性,如下:
bottomNavigationBar: BottomNavigationBar(
items: tabs,
onTap: _onTapHandler,
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
fixedColor: Colors.red,
unselectedItemColor: Colors.black87,
backgroundColor: Colors.white,
),
其中_onTapHandler是點(diǎn)擊item時(shí)觸發(fā)的回調(diào)函數(shù),
//當(dāng)前點(diǎn)擊的item
int _currentIndex = 0;
//點(diǎn)擊底部item跳轉(zhuǎn)相應(yīng)的page
void _onTapHandler(int index) {
setState(() {
_currentIndex = index;
});
}
-
Scaffold的body屬性放置一個(gè)IndexedStack,其在同一時(shí)刻只能顯示子控件中的一個(gè)控件,通過Index屬性來設(shè)置顯示的控件。故完整的Scaffold設(shè)置如下:
return Scaffold(
body: IndexedStack(
index: _currentIndex,
children: _pages,
),
bottomNavigationBar: BottomNavigationBar(
items: tabs,
onTap: _onTapHandler,
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
fixedColor: Colors.red,
unselectedItemColor: Colors.black87,
backgroundColor: Colors.white,
),
);
?傳送門 喜歡的請(qǐng)給個(gè)Star ☆