【问题标题】:Flutter Drawer below AppBarAppBar 下方的 Flutter Drawer
【发布时间】: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 样式,但客户希望它像以前一样。

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

【问题讨论】:

    标签: flutter drawer appbar flutter-layout


    【解决方案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(),
      

      【讨论】:

        猜你喜欢
        • 2021-03-23
        • 2021-06-28
        • 2018-08-09
        • 2023-01-04
        • 2021-11-25
        • 2021-10-21
        • 2017-09-20
        • 2016-06-16
        • 2020-06-11
        相关资源
        最近更新 更多