- 建立導(dǎo)航組件
- 理解有狀態(tài)組件和無狀態(tài)組件
- VScode 添加Awesome Flutter Snippets 插件 - 快速生成頁面代碼
- 數(shù)組..add() 方法
- onTap() 底部導(dǎo)航點(diǎn)擊事件
- currentIndex 底部導(dǎo)航組件選擇高亮
我們經(jīng)吃剖可以發(fā)現(xiàn)移動(dòng)端的布局形式,喜歡在底部有一個(gè)類型的導(dǎo)航,一般包括首頁,分類,購物車以及個(gè)人中心的選項(xiàng)卡,當(dāng)點(diǎn)擊時(shí)分別跳進(jìn)不同的頁面,以京東為例:
首先,我們需要建立一個(gè)主頁面:
import 'package:flutter/material.dart';
import 'BottomNavigationWidget.dart';
void mian(){
runApp(MyApp());
}
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'beline App',
theme: ThemeData.light(), //- 主題顏色
home: BottomNavgationWidget()
);
}
}
主頁面中,我們在MaterialApp
組件中使用了theme
的屬性,是主題屬性,那么參數(shù)ThemeData.light
是一個(gè)亮色.還有其他屬性可以參考API
這里我們新建了一個(gè)組件BottomNavigationWidget.dart
,直接在home中放置.
接下來,我們需要建立BottomNavigationWidget.dart
這里需要了解一下無狀態(tài)組件(Stateless widget
)和有狀態(tài)組件(Stateless widget
)
無狀態(tài)組件 or 有狀態(tài)組件
我們前面寫的class
都是繼承自StatelessWidget
無狀態(tài)組件.這里先對狀態(tài)組件做一個(gè)簡單的區(qū)分,后續(xù)會詳細(xì)講
-
Stateful widget
可以擁有狀態(tài)亲桥,這些狀態(tài)在widget
生命周期中是可以變的辽慕,而Stateless widget
是不可變的。 - Stateful widget至少由兩個(gè)類組成:
- 一個(gè)
StatefulWidget
類苟跪。 - 一個(gè)
State
類;StatefulWidget
類本身是不變的锣披,但是State
類中持有的狀態(tài)在widget
生命周期中可能會發(fā)生變化精续。
- 一個(gè)
_BottomNavgationWidgetState
類是BottomNavgationWidget
類對應(yīng)的狀態(tài)類. _BottomNavgationWidgetState
類中并沒有build方法,取而代之的是婚脱,build方法被挪到了BottomNavgationWidget
方法中
Awesome Flutter Snippets 插件 - 快速生成頁面代碼
這里如果我們安裝了VScode插件Awesome Flutter Snippets
就可以通過命令stful
直接生成
這里把插件的圖也截出來,避免下載錯(cuò)誤
接下來我們需要在
_BottomNavgationWidgetState
中寫我們的地步導(dǎo)航,和普通的類的寫法并沒有特別的區(qū)別,我們需要retuen
一個(gè)Scaffold()
,里面裝一個(gè)bottomNavigationBar: BottomNavigationBar()
,這個(gè)就是底部導(dǎo)航組件,然后通過items中傳入widget數(shù)組,每個(gè)對應(yīng)一個(gè)下面的導(dǎo)航按鈕BottomNavigationBarItem()
.可以分別設(shè)置icons()
圖標(biāo)和title屬性.
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
color: Colors.blue,
),
title: Text(
'首頁',
style:TextStyle(color: Colors.blue)
)
),
]
),
完整代碼如下:
import 'package:flutter/material.dart';
//- 動(dòng)態(tài)Widget stful
class BottomNavgationWidget extends StatefulWidget {
@override
_BottomNavgationWidgetState createState() => _BottomNavgationWidgetState();
}
class _BottomNavgationWidgetState extends State<BottomNavgationWidget> {
final _BottomNavgationColor = Colors.blue;
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
color: _BottomNavgationColor,
),
title: Text(
'首頁',
style:TextStyle(color: _BottomNavgationColor)
)
),
BottomNavigationBarItem(
icon: Icon(
Icons.donut_large,
color: _BottomNavgationColor,
),
title: Text(
'分類',
style:TextStyle(color: _BottomNavgationColor)
)
),
BottomNavigationBarItem(
icon: Icon(
Icons.search,
color: _BottomNavgationColor,
),
title: Text(
'發(fā)現(xiàn)',
style:TextStyle(color: _BottomNavgationColor)
)
),
BottomNavigationBarItem(
icon: Icon(
Icons.shop,
color: _BottomNavgationColor,
),
title: Text(
'購物車',
style:TextStyle(color: _BottomNavgationColor)
)
),
BottomNavigationBarItem(
icon: Icon(
Icons.account_circle,
color: _BottomNavgationColor,
),
title: Text(
'我的',
style:TextStyle(color: _BottomNavgationColor)
)
)
]
),
);
}
}
然后我們運(yùn)行虛擬機(jī),看一下底部導(dǎo)航欄的效果:
..add() 方法
我們前面已經(jīng)把底部導(dǎo)航已經(jīng)顯示出來了,還不能點(diǎn)擊.我們需要簡單的建5個(gè)頁面,用于底部導(dǎo)航的跳轉(zhuǎn).
5個(gè)簡單的頁面都類似下面的結(jié)構(gòu),只是簡單的一個(gè)Text組件用于區(qū)分頁面
home.dart
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Home Pages')),
body: Center(
child: Text('Home Pages'),
)
);
}
}
把這5個(gè)頁面分別引入底部組件的dart
import 'pages/home.dart';
import 'pages/shop.dart';
import 'pages/usercenter.dart';
import 'pages/faxian.dart';
import 'pages/fenlei.dart';
先在State
類中聲明一個(gè)list
數(shù)組,此時(shí)我們可以使用..add()
方法,分別把各個(gè)組件添加到pagelist
變量中
void initState() {
//- 通過..add()方法添加各個(gè)組件到pagelist
pagelist
..add(HomeScreen())
..add(FenLeiScreen())
..add(FaxianScreen())
..add(ShopScreen())
..add(UserCenterScreen());
super.initState();
}
onTap() 底部導(dǎo)航點(diǎn)擊事件
我們前面已經(jīng)把各個(gè)頁面引入到底部導(dǎo)航菜單,這個(gè)時(shí)候,我們需要進(jìn)行切換功能.
首先,在State類中聲明一個(gè)變量_currentIndex
用于存放指定使用pagelist變量中的組件
然后通過給底部導(dǎo)航欄添加事件,這里需要傳入index
,獲取點(diǎn)擊的是第幾個(gè),并賦值給_currentIndex
變量
onTap: (int index) {
setState(() {
_currentIndex = index;
});
},
我們在前面引入了底部導(dǎo)航,并沒有引入body
,此時(shí)有頁面了,我們可以加上,并通過下標(biāo)返回pagelist
中存放的頁面組件顯示的body上
body: pagelist[_currentIndex],
_currentIndex 底部導(dǎo)航組件選擇高亮
在底部導(dǎo)航組件中有一個(gè)屬性,當(dāng)你選中這個(gè)組件的時(shí)候,會有選中樣式
currentIndex: _currentIndex,
完整代碼:
import 'package:flutter/material.dart';
import 'pages/home.dart';
import 'pages/shop.dart';
import 'pages/usercenter.dart';
import 'pages/faxian.dart';
import 'pages/fenlei.dart';
//- 動(dòng)態(tài)Widget stful
class BottomNavgationWidget extends StatefulWidget {
@override
_BottomNavgationWidgetState createState() => _BottomNavgationWidgetState();
}
class _BottomNavgationWidgetState extends State<BottomNavgationWidget> {
final _BottomNavgationColor = Colors.blue;
int _currentIndex = 0;
List<Widget> pagelist = List();
@override
void initState() {
//- 通過..add()方法添加各個(gè)組件到pagelist
pagelist
..add(HomeScreen())
..add(FenLeiScreen())
..add(FaxianScreen())
..add(ShopScreen())
..add(UserCenterScreen());
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: pagelist[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
color: _BottomNavgationColor,
),
title: Text(
'首頁',
style:TextStyle(color: _BottomNavgationColor)
)
),
BottomNavigationBarItem(
icon: Icon(
Icons.donut_large,
color: _BottomNavgationColor,
),
title: Text(
'分類',
style:TextStyle(color: _BottomNavgationColor)
)
),
BottomNavigationBarItem(
icon: Icon(
Icons.search,
color: _BottomNavgationColor,
),
title: Text(
'發(fā)現(xiàn)',
style:TextStyle(color: _BottomNavgationColor)
)
),
BottomNavigationBarItem(
icon: Icon(
Icons.shop,
color: _BottomNavgationColor,
),
title: Text(
'購物車',
style:TextStyle(color: _BottomNavgationColor)
)
),
BottomNavigationBarItem(
icon: Icon(
Icons.account_circle,
color: _BottomNavgationColor,
),
title: Text(
'我的',
style:TextStyle(color: _BottomNavgationColor)
)
)
],
currentIndex: _currentIndex,
onTap: (int index) {
setState(() {
_currentIndex = index;
});
},
),
);
}
}