Flutter 实现钉钉侧边栏
Flutter framework 自带了很多好用的 Widget
实现一个侧边栏效果可以使用 Drawer Widget
实现步骤
在 DTMainScreen 的 Scaffold 添加 drawer 属性,使用 Drawer widget来展示
Drawer 的 child 属性可以使用自定义 widget 来填充(ListView)
DTMessageScreen 添加点击事件,打开 Drawer
onTap: () {
Scaffold.of(context).openDrawer();
},
修改 DTMainScreen
- 添加 drawer 属性
@override
Widget build(BuildContext context) {
ScreenUtil.init(context, width: 750, height: 1334);
super.build(context);
return Scaffold(
drawer: Drawer(child: DTMainDrawerContent(),),
body: _buildPageView(),
....
自定义 DTMainDrawerContent 组件
class DTMainDrawerContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
child: Container(
margin: EdgeInsets.symmetric(horizontal: kSize36),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
DTDrawerUserInfoView(),
DTDrawerWorkStatusView(),
DTDrawerListContentView()
],
),
),
),
);
}
}
- SafeArea 使用安全区域,适配 iPhone X etc…
- SingleChildScrollView 来包裹填充自组件
DTDrawerUserInfoView
class DTDrawerUserInfoView extends StatelessWidget {
const DTDrawerUserInfoView({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"江景",
style: TextStyle(fontSize: kSize40, fontWeight: FontWeight.bold),
),
Padding(
padding: EdgeInsets.only(top: kSize10),
child: Text(
"您所提出的问题,争取满意百分之百。",
style: TextStyle(fontSize: kSize30, color: kColor33),
overflow: TextOverflow.ellipsis,
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: kSize20),
child: Image.asset(
'assets/images/icon_org_auth_advance.png',
width: kSize140,
fit: BoxFit.cover,
),
),
],
)),
GestureDetector(
child: CircleAvatar(
backgroundColor: kPrimaryColor,
radius: kSize40,
child: Text(
"江景",
style: TextStyle(color: Colors.white),
),
),
onTap: () {},
)
],
);
}
}
DTDrawerWorkStatusView
class DTDrawerWorkStatusView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(vertical: kSize40),
padding: EdgeInsets.symmetric(vertical: kSize16),
decoration: BoxDecoration(
color: kColorECEDED,
borderRadius: BorderRadius.all(Radius.circular(kSize20))),
width: double.infinity,
child: Padding(
padding: EdgeInsets.only(left: kSize26),
child: Text(
"编辑工作状态...",
style: TextStyle(color: kColor99, fontSize: kSize26),
),
),
);
}
}
DTDrawerListContentView
因为放在 SingleChildScrollView 中,所以可以使用 Column 来展示 ListView 效果
显示 Item 都是差不多,可以封装一个自定义 Widget,DTListContentItem
class DTDrawerListContentView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
DTListContentItem(
leading: SvgPicture.asset('assets/icons/icon_qrcode.svg',
width: kSize48, color: Colors.green),
title: "二维码名片",
trailing: SvgPicture.asset('assets/icons/icon_qrcode.svg',
color: kColor99, width: kSize48),
),
....
],
);
}
}
DTListContentItem
class DTListContentItem extends StatelessWidget {
final Widget leading;
final Widget trailing;
final String title;
DTListContentItem({this.leading, this.title, this.trailing});
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(vertical: kSize30),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
leading ?? SizedBox(),
title != null
? Padding(
padding: EdgeInsets.only(left: kSize28),
child: Text(
title ?? "",
style: TextStyle(color: kColor33, fontSize: kSize34),
),
)
: SizedBox(),
],
),
Row(
children: <Widget>[
trailing ?? SizedBox(),
SvgPicture.asset(
'assets/icons/icon_arrow_right.svg',
width: kSize38,
color: kColor99,
),
],
)
],
),
);
}
}
总结:在 Flutter 中,一切皆为 Widget,再复杂的 UI 显示,都可以使用一个个小的 Widget 来拼装组成。