Flutter 構(gòu)建一個常用的頁面框架
最終實現(xiàn)的結(jié)果如上圖所示,頂部共用一個導航欄,底部有四個圖標導航,點擊對應的圖標跳轉(zhuǎn)到對應的頁面。
圖標準備
本次例程需要4個圖標,2種顏色,可以從 iconfont 中找到自己需要的圖標下載不同的顏色使用。然后在 pubspec.yaml 中的 assets 指定素材所在目錄。需要注意的是如果是 png 文件直接指定整個目錄即可,但如果是 jpg 格式,則需要同時指定文件名及后綴。
BottomNavigationBar 簡介
BottomNavigationBar的構(gòu)造函數(shù)如下:
BottomNavigationBar({ Key? key, required this.items, this.onTap, this.currentIndex = 0, this.elevation, this.type, Color? fixedColor, this.backgroundColor, this.iconSize = 24.0, Color? selectedItemColor, this.unselectedItemColor, this.selectedIconTheme, this.unselectedIconTheme, this.selectedFontSize = 14.0, this.unselectedFontSize = 12.0, this.selectedLabelStyle, this.unselectedLabelStyle, this.showSelectedLabels, this.showUnselectedLabels, this.mouseCursor, })
其中常用的屬性為:
- items:及對應的頁面組件數(shù)組
- currentIndex:默認顯示第幾個頁面
- type:組件類型,使用BottomNavigationBarType枚舉,有 fixed 和 shifting 兩種。fixed 是圖標固定位置,而 shifting 的圖標點擊后會有一個漂移效果,可以實際試一下,一般用fixed 比較多。
- onTap:點擊后的事件,一般用這個更新狀態(tài)數(shù)據(jù),以便更新頁面。
其他屬性用于控制樣式的,可以根據(jù)實際需要設置圖標大小,主題色,字體等參數(shù)。
構(gòu)建項目頁面結(jié)構(gòu)
首先,新建四個業(yè)務頁面,分別是 dynamic.dart,message.dart,category.dart 和 mine.dart,分別對應動態(tài)、消息、分類瀏覽和個人中心四個頁面。目前這四個頁面很簡單,只是在頁面中間依次顯示“島上碼農(nóng)”四個字。代碼都是類似的,以 dynamic 為例:
import 'package:flutter/material.dart'; class DynamicPage extends StatelessWidget { const DynamicPage({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Text('島'), ), ); } }
注意的是這里的 Scaffold 沒有 AppBar 了,這是因為在首頁已經(jīng)有了,如果再有 AppBar 就會出現(xiàn)兩個。
其次,新建首頁,用于管理四個業(yè)務頁面,命名為 app.dart。app.dart 使用了 BottomNavigationBar 管理四個業(yè)務頁面的切換。
import 'package:flutter/material.dart'; import 'dynamic.dart'; import 'message.dart'; import 'category.dart'; import 'mine.dart'; class AppHomePage extends StatefulWidget { AppHomePage({Key key}) : super(key: key); @override _AppHomePageState createState() => _AppHomePageState(); } class _AppHomePageState extends State<AppHomePage> { int _index = 0; List<Widget> _homeWidgets = [ DynamicPage(), MessagePage(), CategoryPage(), MinePage(), ]; void _onBottomNagigationBarTapped(index) { setState(() { _index = index; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('島上碼農(nóng)'), ), body: IndexedStack( index: _index, children: _homeWidgets, ), bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, currentIndex: _index, onTap: _onBottomNagigationBarTapped, items: [ _getBottomNavItem( '動態(tài)', 'images/dynamic.png', 'images/dynamic-hover.png', 0), _getBottomNavItem( ' 消息', 'images/message.png', 'images/message-hover.png', 1), _getBottomNavItem( '分類瀏覽', 'images/category.png', 'images/category-hover.png', 2), _getBottomNavItem( '個人中心', 'images/mine.png', 'images/mine-hover.png', 3), ], ), ); } BottomNavigationBarItem _getBottomNavItem( String title, String normalIcon, String pressedIcon, int index) { return BottomNavigationBarItem( icon: _index == index ? Image.asset( pressedIcon, width: 32, height: 28, ) : Image.asset( normalIcon, width: 32, height: 28, ), label: title, ); } }
這里關(guān)鍵的地方有兩個,一是使用的 IndexedStack,這是一個管理頁面顯示層級的容器。使用 index 屬性確定當前容器里那個頁面在最頂上,容器里的頁面通過 children 屬性設置,要求是一個 Widget 數(shù)組。因此,邏輯就是當 BottomNavigationBar 中的圖標被點擊后,對應點擊事件會回調(diào) onTap屬性指定的方法,將當前的點擊索引值傳遞回調(diào)函數(shù),因此可以利用這個方式控制 IndexedStack 的頁面層級切換。
最后,使用了狀態(tài)變量_index 存儲IndexedStatck當前顯示頁面的索引值,然后當 BottomNavigationBar的圖標點擊事件發(fā)生后,在回調(diào)函數(shù)中使用 setState 更新狀態(tài)變量_index 來刷新當前界面。
簡化入口
main.dart 是入口文件,應當做最基礎(chǔ)的配置和全局初始化配置,而不應該有業(yè)務代碼,因此可以簡化為從main 方法加載首頁即可。通過這種方式可以讓 main.dart 文件即為簡潔。這也是在開發(fā)的時候需要注意的地方,將不相關(guān)的代碼剝離,相關(guān)的代碼聚合,即所謂的“高內(nèi)聚,低耦合”原則。
import 'package:flutter/material.dart'; import 'app.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'App 框架', theme: ThemeData( primarySwatch: Colors.blue, ), home: AppHomePage(), ); } }
代碼復用
寫代碼的時候要注意復用,在這里將構(gòu)建 BottomNavigationBar 元素抽離出了一個構(gòu)建方法_getBottomNavItem,從而提高代碼的復用性和維護性,也可以避免 Flutter 的組件構(gòu)建的 build 方法中出現(xiàn)過多的元素和嵌套,影響代碼的可讀性。
以上就是Flutter 構(gòu)建一個常用的頁面框架的詳細內(nèi)容,更多關(guān)于Flutter 構(gòu)建頁面框架的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android AlertDialog六種創(chuàng)建方式案例詳解
這篇文章主要介紹了Android AlertDialog六種創(chuàng)建方式案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08ListView的View回收引起的checkbox狀態(tài)改變監(jiān)聽等問題解決方案
之前講到了自定義Adapter傳遞給ListView時,因為ListView的View回收,需要注意當ListView列表項中包含有帶有狀態(tài)標識控件的問題,感興趣的朋友可以祥看本文,或許會有意外的收獲哦2013-01-01