AppBar 下方的 Flutter Drawer

Posted

技术标签:

【中文标题】AppBar 下方的 Flutter Drawer【英文标题】:Flutter Drawer below AppBar 【发布时间】:2019-01-04 00:25:08 【问题描述】:

我在我的Flutter 应用程序中实现了Drawer

已关闭Drawer:

打开Drawer:

如您所见,Drawer 位于Appbar 之上。在我在Flutter 上启动应用程序之前,我们有一个原生的android 应用程序和一个Drawer,它曾经看起来像这样:

已关闭Drawer:

打开Drawer:

这是我的代码:

class MyDrawer extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return _buildDrawer(context);
  


Widget _buildDrawer(BuildContext context) 
  return new Drawer(
    child: new ListView(
      children: <Widget>[
        _buildDrawerItem(context, EnumDrawerItem.PROJECT_SELECTION, Icons.home, Colors.transparent),
        new Divider(height: 20.0),
        _buildDrawerItem(context, EnumDrawerItem.TASK_LIST, Icons.home, Colors.transparent),
        new Divider(),
        _buildDrawerItem(context, EnumDrawerItem.GUIDED_TASKS, Icons.home, Colors.transparent),
        new Divider(),
        _buildDrawerItem(context, EnumDrawerItem.PHOTOS, Icons.home, Colors.transparent),
        new Divider(),
        _buildDrawerItem(context, EnumDrawerItem.DOCUMENTS, Icons.home, Colors.transparent),
        new Divider(),
        _buildDrawerItem(context, EnumDrawerItem.LOG_OUT, Icons.home, const Color(0x85bf0202)),
        new Divider(),
      ],
    ),
  );


Widget _buildDrawerItem(BuildContext context, EnumDrawerItem drawerItem, IconData iconData, Color color) 
  return  Container(
    color: color,
    child: new Padding(
      padding: new EdgeInsets.all(7.0),
      child: new Row(
        children: <Widget>[
          new Icon(iconData),
          new Container(
            margin: new EdgeInsets.fromLTRB(10.0, 0.0, 0.0, 0.0),
            child: new Text(
              drawerItem.toString(),
              style: styleDrawerItem,
            ),
          ),
        ],
      ),
    ),
  );

我知道这是标准的Material Design 样式,但客户希望它像以前一样。

是否可以像最后两张截图一样实现它?你有什么想法吗?

【问题讨论】:

【参考方案1】:

将您的主要Scaffold 包装在另一个Scaffold 中并使用子Scaffold 的抽屉,同时确保将automaticallyImplyLeading 设置为false,这样您就不会在AppBar 中找回图标

更新: 我不推荐这种方式,因为issue

return Scaffold(
      primary: true,
      appBar: AppBar(
        title: Text("Parent Scaffold"),
        automaticallyImplyLeading: false,
      ),
      body: Scaffold(
        drawer: Drawer(),
      ),
    );

最终结果:

【讨论】:

非常感谢您花时间帮助我。最后一个问题:是否可以将Drawer 图标保留在Appbar 中?如您所见,关闭时有一个drawer 图标,打开时有一个后退箭头。谢谢! 是的,您可以使用父 AppBar 中的图标如您所愿使用Leading 属性,正如我在回答中提到的,如果您希望将图标自动设置为ImplyLeading 为true 好吧,我试试看。谢谢你,非常感谢你的帮助:) 我删除了AppBar 中的automaticallyImplyLeading 属性。现在,当Drawer 打开时我得到了后退箭头,但Drawer 关闭时没有图标:(你能检查一下gif吗?recordit.co/IdRFflKuEH 尝试使用前导属性提供默认图标【参考方案2】:

我在示例中如何使用脚手架中的键和脚手架主体中的引用

GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey();

return Scaffold(
  appBar: AppBar(
      title: Text('Draw'),
      leading: IconButton(
          icon: Icon(Icons.dehaze),
          onPressed: () 
            if (_scaffoldKey.currentState.isDrawerOpen == false) 
              _scaffoldKey.currentState.openDrawer();
             else 
              _scaffoldKey.currentState.openEndDrawer();
            
          )),
  body: Scaffold(
    key: _scaffoldKey,
    drawer: Drawer(),
    body: Center(
      child: Text('Drawer'),
    ),
  ),
);

【讨论】:

【参考方案3】:

试试这个:

class HomePage extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    var statusBarHeight = MediaQuery.of(context).padding.top;
    var appBarHeight = kToolbarHeight;  //this value comes from constants.dart and equals to 56.0
    return Scaffold(
      drawerScrimColor: Colors.transparent,
      appBar: AppBar(),
      drawer: Container(
        padding: EdgeInsets.only(top: statusBarHeight+ appBarHeight + 1),//adding one pixel for appbar shadow
        width: MediaQuery.of(context).size.width,
        child: Drawer(),//write your drawer code
      ),
      body: AnyBody(), //add your body
      bottomNavigationBar: AnyNavigationBar(), //add your navigation bar
    );
  

【讨论】:

不要在 HomePage 构建器函数中触发 MediaQuery,它会通过每次更改 MediaQuery 值来重建所有内容,并会降低性能。最好将您的 Container 移动到自定义小部件中并在其构建功能上使用 MediaQuery【参考方案4】:

简单明了:

drawer: Padding(
    padding: const EdgeInsets.fromLTRB(0, 80, 0, 0),
    child: Drawer(),

【讨论】:

以上是关于AppBar 下方的 Flutter Drawer的主要内容,如果未能解决你的问题,请参考以下文章

Flutter之抽屉组件drawer,设置drawer宽度——Flutter基础系列

Flutter -- 基础组件AppBar 的使用

Material UI Drawer 不会在 Appbar 下移动

Flutter 导航推送,同时保持 Appbar 不变

没有 AppBar 的 Flutter 布局

Material UI - 在 AppBar 点击打开 LeftNav / Drawer