前言

在学习flutter的时候碰到了Drawer这个Widget,但是在使用的过程中有这么一个需求,我想修改他的宽度,网上搜了一圈没找到对应的api。自己也是经过一番折腾才解决的,可能是因为我还是flutter小白把!不管怎样,记录一下,下次遇到问题,好解决。

解决过程

这里上个图就好了,代码就先不上了,毕竟下面会有最终代码。

初始效果

源码

可以看到的是_kWidth字段是私有的,是没有办法被外部访问或修改的,然而,宽度的大小控制就是跟这个字段息息相关的,如下图

_width这个才是真正的宽度(真正的宽度的大小是根据这个变量计算出来的),但是可以发现这个也是私有的,不能被外部访问和篡改。那么,该怎样处理呢?不要怕,重写这个类不就可以了么!重写这个类,把需要的加进去就可以实现了。

重写CustomDrawer类

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
// 为了简单,里面一切处理没写,可以参照官方的,或者把官方的拷贝过来,在官方的基础上进行修改,都是可以的
class CustomDrawer extends StatelessWidget {
final double elevation;
final Widget child;
final String semanticLabel;
final double widthPercent;
const CustomDrawer({
Key key,
this.elevation = 16.0,
this.child,
this.semanticLabel,
this.widthPercent = 0.7,
}) : assert(
widthPercent != null && widthPercent < 1.0 && widthPercent > 0.0),
super(key: key);
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
String label = semanticLabel;
final double _width = MediaQuery.of(context).size.width * widthPercent;
return Semantics(
scopesRoute: true,
namesRoute: true,
explicitChildNodes: true,
label: label,
child: ConstrainedBox(
constraints: BoxConstraints.expand(width: _width),
child: Material(
elevation: elevation,
child: child,
),
),
);
}
}

使用重写都的CustomDrawer类

既然重构好了,就还等什么,赶紧使用吧!

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
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(S.current.title),
),
drawer: _drawer,
);
}

get _drawer {
var listView = ListView(
//1
padding: EdgeInsets.zero,
children: <Widget>[
UserAccountsDrawerHeader(
accountName: Text('Yunjiege'),
accountEmail: Text('1329712473@qq.com'),
currentAccountPicture: CircleAvatar(
child: Text('X'),
),
),
ListTile(
leading: Icon(Icons.local_post_office),
title: Text('邮件'),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('设置'),
)
],
);
return new CustomDrawer(
widthPercent: 0.7,//这里控制抽屉的弯度,不能小于0,不能大于1
child: listView,
);
}
}

效果图和完整代码

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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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('开车cn'),
),
drawer: _drawer,
);
}

get _drawer {
var listView = ListView(
//1
padding: EdgeInsets.zero,
children: <Widget>[
UserAccountsDrawerHeader(
accountName: Text('Yunjiege'),
accountEmail: Text('1329712473@qq.com'),
currentAccountPicture: CircleAvatar(
child: Text('X'),
),
),
ListTile(
leading: Icon(Icons.local_post_office),
title: Text('邮件'),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('设置'),
)
],
);
return new CustomDrawer(
widthPercent: 0.5,
child: listView,
);
}
}

class CustomDrawer extends StatelessWidget {
final double elevation;
final Widget child;
final String semanticLabel;
final double widthPercent;
const CustomDrawer({
Key key,
this.elevation = 16.0,
this.child,
this.semanticLabel,
this.widthPercent = 0.7,
}) : assert(
widthPercent != null && widthPercent < 1.0 && widthPercent > 0.0),
super(key: key);
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
String label = semanticLabel;
final double _width = MediaQuery.of(context).size.width * widthPercent;
return Semantics(
scopesRoute: true,
namesRoute: true,
explicitChildNodes: true,
label: label,
child: ConstrainedBox(
constraints: BoxConstraints.expand(width: _width),
child: Material(
elevation: elevation,
child: child,
),
),
);
}
}

总结

其实并不复杂,只要知道自己的需求就好,然后根据自己的需求寻找问题,找到问题的根本。然后以最好的方式去解决(本人这个方法不造是不是好的)。其实吧,发现Drawer组件和原生android里的DrawerLayout是差不多的(大学学过android)。


如果能够帮助到你,是小编最大的荣幸

当然 有 不好的地方 请大家帮忙指出 学习永无止境

小编一直认为 人外有人 天外有天 一起学习 共同进步

让我们共同加油吧!!!