Flutter Scaffold.of(context).openDrawer()不工作

mkh04yzy  于 2023-05-29  发布在  Flutter
关注(0)|答案(9)|浏览(329)

我想打开一个抽屉后按下自定义按钮在底部菜单我有问题的Scaffold.of(context).openDrawer(),它不工作。My BottomMenu是一个单独的widget类。据我所知,它不起作用,因为它是一个单独的上下文。我怎样才能获得正确的上下文?也许有人知道另一个解决方案。
下面是我的代码再现器:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(title: 'Flutter Drawer'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      bottomNavigationBar: BottomMenu(),
      endDrawer: SizedBox(
        width: double.infinity,
        child: Drawer(
          elevation: 16,
          child: Container(
            color: Colors.black,
            child: ListView(
              padding: EdgeInsets.zero,
              children: <Widget>[
                ListTile(
                    title: Text('Some context here',
                        style: TextStyle(color: Colors.white))),
                ListTile(
                    title: Text('Some context here',
                        style: TextStyle(color: Colors.white))),
              ],
            ),
          ),
        ),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Call Drawer form menu reproducer',
            )
          ],
        ),
      ),
    );
  }
}

class BottomMenu extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 15),
      child: Wrap(
        alignment: WrapAlignment.center,
        children: <Widget>[
          Divider(color: Colors.black, height: 1),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 2),
            child: Row(
                mainAxisSize: MainAxisSize.max,
                mainAxisAlignment: MainAxisAlignment.end,
                children: <Widget>[
                  InkWell(
                    borderRadius: new BorderRadius.circular(20.0),
                    customBorder: Border.all(color: Colors.black),
                    child: Container(
                      padding: EdgeInsets.only(
                          left: 3, right: 6, bottom: 15, top: 11),
                      child: Row(
                        children: <Widget>[
                          Icon(Icons.menu),
                          Text('Show menu', style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold)),
                        ],
                      ),
                    ),
                    onTap: () {
                      Scaffold.of(context).openDrawer();
                    },
                  ),
                ],
              ),
          ),
        ],
      ),
    );
  }
}
pepwfjgg

pepwfjgg1#

在我的情况下,这起作用了。

return Scaffold(
      key: _scaffoldKey,
      endDrawerEnableOpenDragGesture: false,  // This!
      appBar: AppBar(
        iconTheme: IconThemeData(color: Colors.white),
        leading: IconButton(
          icon: Icon(Icons.menu, size: 36),
          onPressed: () => _scaffoldKey.currentState.openDrawer(),  // And this!
        ),
      ),
      drawer: DrawerHome(),
      ....

并且_scaffoldKey必须被初始化为,

final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

在班级下面。

v1uwarro

v1uwarro2#

问题是您在Scaffold上指定了endDrawer,但您调用的是Scaffold.of(context).openDrawer()
openDrawer()文档说明:
如果脚手架有一个非空Scaffold.drawer,这个函数将导致抽屉开始它的入口动画。
因为drawer是null,所以什么都没有发生。
相反,openEndDrawer()告诉我们:
如果脚手架具有非空Scaffold.endDrawer,则此函数将导致末端抽屉开始其入口动画。
因为endDrawer不是null,所以应该使用openEndDrawer()方法。或者,如果您不关心抽屉从哪一侧滑入,则可以在构建Scaffold时使用drawer而不是endDrawer

mzaanser

mzaanser3#

我的问题解决了这个问题而不是

Scaffold.of(context).openEndDrawer()

我把钥匙交给Scaffold然后我按如下状态打电话

_scaffoldkey.currentState.openEndDrawer()

它解决了我的问题,我希望它也适用于你

xurqigkl

xurqigkl4#

Scaffold.of(context).openEndDrawer()
qqrboqgw

qqrboqgw5#

  • 问题 *

如果在调用Scaffold.of(context).openDrawer()(或openEndDrawer())时未使用正确的BuildContext,则可能会出现此问题。

最简单的解决方案

只需使用Builder小部件 Package 调用openDrawer()(或openEndDrawer())的任何内容。这将给予它一个工作context

最小工作示例

// your build method
@override
Widget build(BuildContext context) {
  return Scaffold(
    floatingActionButton: Builder(builder: (context) { // this uses the new context to open the drawer properly provided by the Builder
      return FloatingActionButton(onPressed: (() => Scaffold.of(context).openDrawer())); 
    }),
    drawer: const Drawer(
      child: Text("MY DRAWER"),
    ),
  );
}
r6l8ljro

r6l8ljro6#

类似的问题在这里。点击按钮,什么也没发生。问题是我正在使用示例化Scaffold的小部件的上下文。不是脚手架的孩子的背景。
我是如何解决它的:

// body: Column(
        //   children: <Widget>[
        //     Row(
        //       children: <Widget>[        
        //         IconButton(
        //           icon: Icon(Icons.filter_list),
        //           onPressed: () => Scaffold.of(context).openEndDrawer(), (wrong context)
        //         ),
        //       ],
        //     ),
        //   ],
        // )

收件人:

body: Builder(
            builder: (context) => Column(
                  children: <Widget>[
                    Row(
                      children: <Widget>[
                        IconButton(
                          icon: Icon(Icons.filter_list),
                          onPressed: () => Scaffold.of(context).openEndDrawer(),
                        ),
                      ],
                    ),
                  ],
                )),
      ),
weylhg0b

weylhg0b7#

将Drawer分配给脚手架中的drawer属性。使用Builder Package 您的特定Widget/Button(您希望在其单击方法上打开抽屉的位置)。点击属性时使用以下方法:enter image description here Scaffold.of(context).openDrawer();

mu0hgdu0

mu0hgdu08#

你需要wrap Builder,像这样:

AppBar(
                leading: Builder(
                  builder: (context) {
                    return IconButton(
                      icon: Icon(Icons.abc_outlined),
                      onPressed: () {
                        Scaffold.of(context).openDrawer();
                      },
                    );
                  }
                ),
//...//

它为我工作!

ego6inou

ego6inou9#

如果你有一个带有操作按钮的appbar小部件来启动抽屉,并且抽屉永远不会被推,请记住,你需要在appbar: ...之后定义endDrawer: YOURAppDrawerWIDGET(),,否则使用Scaffold.of(context).openEndDrawer()将无法工作。

Scaffold(
    appBar: AppBar(title: Text(_title)),
    endDrawer: AppDrawer(), // <-- this is required or else it will not know what is opening
    body: SingleChildScrollView(
     ///...

相关问题