Flutter之AppBar的部分定制

代码 最终预览效果如下:

AppBar定制-min.gif

一、定制Title

目标:App导航栏title换成需要切换条(iOS中叫Segment)
1、flutter提供的AppBar的title属性就是wigdet,所有我们可以直接把title设置为tabbar;
2、需要相应的页面来进行联动,所以需要关联SingleTickerProviderStateMixin, 且把tabbar的controller 和 TabBarView的controller设置为同一个controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
class MyHomePage extends StatefulWidget {
final String title;

MyHomePage({Key key, this.title}) : super(key: key);

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
TabController _controller;
@override
void initState() {
super.initState();
_controller = TabController(length: 3, vsync: this); //初始化方法
}

@override
Widget build(BuildContext context) {
return Scaffold(
title: TabBar(
controller: _controller,
tabs: <Widget>[
Tab(
icon: Icon(Icons.directions_car),
),
Tab(
icon: Icon(Icons.directions_transit),
),
Tab(
icon: Icon(Icons.directions_bike),
),
],
),
),
body: TabBarView(
controller: _controller,
children: <Widget>[
HomePage(
title: "设置11111",
),
HomePage(
title: "设置22222",
),
HomePage(
title: "设置33333",
),
],
),
);
}

HomePage代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class HomePage extends StatelessWidget {
final String title;
final Widget child;

HomePage({Key key, this.child, this.title}) : super(key: key);

@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Text(title),
),
);
}
}

二、侧滑抽屉效果

1、方法一:系统自带(局限性,图片不能更改)
仅仅设置Scaffold的drawer就好

1
drawer: _buildDrawer(context),

2、方法二:Builder

1
2
3
4
5
6
leading: Builder(
builder: (context) => IconButton(
icon: new Icon(Icons.settings),
onPressed: () => Scaffold.of(context).openDrawer(),
),
),

3、方法三:GlobalKey

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// 1.步奏一
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,// 2、步奏二
drawer: _buildDrawer(context),
leading: IconButton(
icon: Icon(Icons.account_box),
onPressed: () {
// 3、步奏三
_scaffoldKey.currentState.openDrawer();
},
),
);
}

4、方法四:改变源码(不推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

/// 到AppBar源码,修改的部分code
Widget leading = widget.leading;
if (/*leading == null && */widget.automaticallyImplyLeading) {
if (hasDrawer) {
leading = IconButton(
icon: /*const Icon(Icons.menu)*/ leading ?? Icon(Icons.home), // 如果leading指定了widget那么
onPressed: _handleDrawerButton,
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
);
} else {
if (canPop)
leading = useCloseButton ? const CloseButton() : const BackButton();
}
}
if (leading != null) {
leading = ConstrainedBox(
constraints: const BoxConstraints.tightFor(width: _kLeadingWidth),
child: leading,
);
}

附录:代码汇总

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Widget _buildDrawer(BuildContext context) {
return Drawer(
child: ListView(
dragStartBehavior: DragStartBehavior.down,
children: <Widget>[
// 1. 简单的头部
// const DrawerHeader(
// child: Center(
// child: Text('我是侧边栏'),
// ),
// ),
// 2.复杂的用户头部
// UserAccountsDrawerHeader 不能用const来修饰
UserAccountsDrawerHeader(
accountEmail: Text(
'13456@qq.com',
style: TextStyle(color: Colors.black),
),
accountName: Text(
'HandsomeMen',
style: TextStyle(color: Colors.black),
),
currentAccountPicture: GestureDetector(
onTap: () {
print('current user');
},
child: CircleAvatar(
backgroundImage: NetworkImage(
'http://m.360buyimg.com/pop/jfs/t25441/342/232745157/35324/69b79175/5b696c57N739592b8.jpg'),
),
),
otherAccountsPictures: <Widget>[
GestureDetector(
onTap: () => print('点击了otherAccountsPictures 111111'),
child: CircleAvatar(
backgroundImage: NetworkImage(
'https://pic.qqtn.com/up/2018-9/15367146917869444.jpg'),
),
),
GestureDetector(
onTap: () => print('点击了otherAccountsPictures 222222'),
child: CircleAvatar(
backgroundImage: NetworkImage(
'http://www.gx8899.com/uploads/allimg/160902/3-160Z2104544.jpg'),
),
),
],
decoration: BoxDecoration(
//装饰器提供背景图片
image: DecorationImage(
fit: BoxFit.fill,
//使用网络图片怎么有问题
image: NetworkImage(
'http://www.86ps.com/UpLoadFiles/jpg/2011-10/2011100912585215837.jpg')
// image: new ExactAssetImage('images/bg.jpg'),
),
),
),

const ListTile(
leading: Icon(Icons.account_box),
title: Text('选卡1'),
),
Divider(),
const ListTile(
leading: Icon(Icons.account_box),
title: Text('选卡1'),
),
Divider(),
const ListTile(
leading: Icon(Icons.account_box),
title: Text('选卡1'),
),
],
),
);
}
------------- End Thank For Your Reading -------------