成為一名優(yōu)秀的Android開發(fā),需要一份完備的知識體系,在這里,讓我們一起成長為自己所想的那樣~。
1.BottomNavigationBar
BottomNavigationBar是底部的導(dǎo)航欄,用于在3到5個的少量視圖中進行選擇。一般情況下,導(dǎo)航欄的選項卡由文本標簽、圖標或兩者結(jié)合的形式組成。 底部導(dǎo)航欄通常與javaScaffold結(jié)合使用,它會作為Scaffold.bottomNavigationBar參數(shù)。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyStatefulWidget(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();//1
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
int _selectedIndex = 0;
static const List<Widget> _widget = <Widget>[
Text(
'Index 0:首頁',
),
Text(
'Index 1: 通訊錄',
),
Text(
'Index 2: 設(shè)置',
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BottomNavigationBar示例'),
),
body: Center(
child: _widget.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('首頁'),
),
BottomNavigationBarItem(
icon: Icon(Icons.contacts),
title: Text('通訊錄'),
),
BottomNavigationBarItem(
icon: Icon(Icons.build),
title: Text('設(shè)置'),
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber,
onTap: _onItemTapped, //2
),
);
}
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
}
復(fù)制代碼
由于使用的Widget需要在Widget的生命周期中改變狀態(tài),因此MyStatefulWidget繼承了StatefulWidget。注釋1處的createState方法會為此Widget創(chuàng)建可變狀態(tài)。注釋2處的onTap屬性會在點擊其中一個選項卡時調(diào)用,它的值由_onItemTapped方法定義,在這個方法中設(shè)置當前的索引賦值給_selectedIndex,這樣通過_selectedIndex的值就可以切換選項卡了。實現(xiàn)的效果如下所示,可以通過點擊選項卡來切換界面。

2.TabBar
TabBar用于顯示水平的選項卡,和Android中的TabLayout類似。TabBar通常需要配合TabBarView和TabController。其中TabBarView用于顯示與當前所選的選項卡對應(yīng)的Widget視圖;TabController顧名思義就是TabBarView和TabBar的控制器,是這兩個Widget的橋梁。實現(xiàn)TabController有兩種方式,一種是用系統(tǒng)的DefaultTabController,另一種是自定義TabController。
2.1 使用DefaultTabController
DefaultTabController這種方式方便快捷,直接新建一個DefaultTabController就可以了。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyTabController(),
);
}
}
class MyTabController extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text('DefaultTabController示例'),
bottom: TabBar(
tabs: <Widget>[
Tab(
text: '熱點',
),
Tab(
text: '體育',
),
Tab(
text: '科技',
),
],
),
),
body: TabBarView(
children: <Widget>[
Center(child: Text('熱點')),
Center(child: Text('體育')),
Center(child: Text('科技')),
],
),
),
);
}
}
復(fù)制代碼
2.2 自定義TabController
如果想要切換動畫或者監(jiān)聽切換的交互,可以自定義TabController,需要實現(xiàn)SingleTickerProviderStateMixin。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyStatefulWidget(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget>
with SingleTickerProviderStateMixin {
TabController _tabController;
void initState() {
super.initState();
_tabController = TabController(vsync: this, length: 3);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('自定義TabController'),
bottom: TabBar(
tabs: <Widget>[
Tab(
text: '熱點',
),
Tab(
text: '體育',
),
Tab(
text: '科技',
),
],
controller: _tabController,//1
),
),
body: TabBarView(
controller: _tabController,
children: <Widget>[
Center(child: Text('熱點')),
Center(child: Text('體育')),
Center(child: Text('科技')),
],
),
);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
}
復(fù)制代碼
和第一種使用DefaultTabController有兩點不同,一個是使用了StatefulWidget,另一個是在注釋1處將TabBar的controller設(shè)置為新建的TabController。運行效果如下所示,可以通過滑動界面和點擊選項卡來切換界面。

3.Drawer
Drawer就是抽屜,可以實現(xiàn)拉出推入的效果,和Android中的DrawerLayout類似。Drawer通常與Scaffold.drawer屬性一起使用,抽屜的子項通常是ListView,其第一個子項是頭部,頭部主要有兩個Widget可以實現(xiàn):
- DrawerHeader:展示基本的信息
- UserAccountsDrawerHeader:展示用戶頭像、用戶名、Email等信息。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyStatefulWidget(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
@override
_DrawerState createState() => _DrawerState();
}
class _DrawerState extends State<MyStatefulWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Drawer例子'),
),
drawer: _drawer,
);
}
get _drawer => Drawer(
child: ListView(//1
padding: EdgeInsets.zero,
children: <Widget>[
UserAccountsDrawerHeader(
accountName: Text('劉望舒'),
accountEmail: Text('liuwangshu.gmail.com'),
currentAccountPicture: CircleAvatar(
child: Text('X'),
),
),
ListTile(
leading: Icon(Icons.local_post_office),
title: Text('郵件'),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('設(shè)置'),
)
],
),
);
}
復(fù)制代碼
跟以往例子不同的是,由于drawer屬性的代碼比較多,為了提高可讀性,我將drawer屬性的值抽取出來,通過getter的形式進行獲取。注釋1處可以看出Drawer的子項為ListView,ListView的通過ListTile來顯示每一個列表項。注釋2使用的是UserAccountsDrawerHeader,可以很輕松的設(shè)置用戶的姓名、郵箱、用戶圖片等。效果如下圖所示:

總結(jié)
加上上一篇文章,我已經(jīng)介紹了Material組件中應(yīng)用程序結(jié)構(gòu)和導(dǎo)航分類中的大部分Widget,另外Material組件所包含的其他的Widget,本系列就不介紹了,想要了解的可以查看文檔:flutter.dev/docs/develo…
作者:劉望舒
鏈接:https://juejin.cn/post/6844903886247952398
來源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。