Flutter Scaffold.of (context) .openDrawer () не работает

Я хочу открыть ящик после нажатия настраиваемой кнопки в BottomMenu. У меня проблемы с Scaffold.of (context) .openDrawer (), это не работает. My BottomMenu - это отдельный класс виджетов. Насколько я понимаю, не работает, потому что это отдельный контекст. Как я могу получить правильный контекст? Или, возможно, кто-то знает другое решение.

Вот мой репродуктор кода:

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();
                    },
                  ),
                ],
              ),
          ),
        ],
      ),
    );
  }
}


person Volodymyr Bilovus    schedule 25.09.2019    source источник


Ответы (6)


Scaffold.of (контекст) .openEndDrawer ()

person chaitanya Harde    schedule 25.09.2019

В моем случае это сработало.

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>();

под класс.

person Hoon    schedule 01.12.2020
comment
Я пробовал это решение, но без добавления endDrawerEnableOpenDragGesture: false,, и оно все равно работало .. :) - person Malwinder Singh; 24.01.2021
comment
Меня устраивает!! , Tq ???? - person prabhu r; 27.02.2021

Проблема в том, что вы указали endDrawer на Scaffold, но звоните Scaffold.of(context).openDrawer().

В документации openDrawer() говорится:

Если у скаффолда есть ненулевой Scaffold.drawer, эта функция заставит выдвижной ящик начать анимацию входа.

Поскольку ваш drawer равен нулю, ничего не происходит.

Напротив, openEndDrawer() сообщает нам:

Если у скаффолда есть ненулевой Scaffold.endDrawer, эта функция заставит крайний боковой ящик начать анимацию входа.

Поскольку ваш endDrawer не равен нулю, вы должны использовать метод openEndDrawer(). В качестве альтернативы, если вам все равно, с какой стороны выдвигается ящик, вы можете использовать drawer вместо endDrawer при создании Scaffold.

person cegas    schedule 25.09.2019

Моя проблема решила это вместо

Scaffold.of(context).openEndDrawer()

Я даю ключ Эшафоту, а затем звоню по штатам, как показано ниже

_scaffoldkey.currentState.openEndDrawer()

Это решило мою проблему, надеюсь, это сработает и для вас

person Shojaeddin    schedule 27.03.2020

Аналогичная проблема здесь. Нажал на кнопку, и ничего не произошло. Проблема в том, что я использовал контекст виджета, создавшего экземпляр Scaffold. Не в контексте дочернего элемента Scaffold.

Вот как я это решил:

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

To:

body: Builder(
            builder: (context) => Column(
                  children: <Widget>[
                    Row(
                      children: <Widget>[
                        IconButton(
                          icon: Icon(Icons.filter_list),
                          onPressed: () => Scaffold.of(context).openEndDrawer(),
                        ),
                      ],
                    ),
                  ],
                )),
      ),
person live-love    schedule 24.04.2020

Если у вас есть виджет панели приложений с кнопкой действия для запуска ящика, а ящик никогда не нажимается, помните, что вам нужно определить после 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(
     ///...
person Daniel C    schedule 24.02.2021