Flutter 实现钉钉侧边栏
Flutter framework 自带了很多好用的 Widget
实现一个侧边栏效果可以使用 Drawer Widget
实现步骤
在 DTMainScreen 的 Scaffold 添加 drawer 属性,使用 Drawer widget来展示
Drawer 的 child 属性可以使用自定义 widget 来填充(ListView)
DTMessageScreen 添加点击事件,打开 Drawer
onTap: () {Scaffold.of(context).openDrawer();},
修改 DTMainScreen
- 添加 drawer 属性
@overrideWidget 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 {@overrideWidget 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);@overrideWidget 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 {@overrideWidget 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 {@overrideWidget 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});@overrideWidget 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 来拼装组成。
