簡體   English   中英

Flutter Scaffold.of(context).openDrawer() 不起作用

[英]Flutter Scaffold.of(context).openDrawer() doesn't work

按下 BottomMenu 中的自定義按鈕后,我想打開一個抽屜我遇到了 Scaffold.of(context).openDrawer() 的問題,它不起作用。 My BottomMenu 是一個單獨的小部件 class。 據我了解,它不起作用,因為它是一個單獨的上下文。 如何獲得正確的上下文? 或者也許有人知道另一種解決方案。

這是我的代碼復制器:

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

就我而言,這行得通。

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

在 class 下。

我的問題解決了,而不是

Scaffold.of(context).openEndDrawer()

我給 Scaffold 鑰匙,然后通過 state 調用,如下所示

_scaffoldkey.currentState.openEndDrawer()

它解決了我的問題我希望它也適用於你

問題是您在Scaffold上指定endDrawer ,但您正在調用Scaffold.of(context).openDrawer()

openDrawer()文檔狀態:

如果腳手架有一個非空的 Scaffold.drawer,這個 function 將導致抽屜開始其入口 animation。

由於您的drawer是 null,因此沒有任何反應。

相反, openEndDrawer()告訴我們:

如果腳手架有一個非空的 Scaffold.endDrawer,這個 function 將導致端側抽屜開始其入口 animation。

由於您的endDrawer不是 null 您應該使用openEndDrawer()方法。 或者,如果您不關心抽屜從哪一側滑入,您可以在構建Scaffold時使用drawer而不是endDrawer

Scaffold.of(context).openEndDrawer()

這里有類似的問題。 單擊按鈕,沒有任何反應。 問題是我正在使用實例化 Scaffold 的小部件的上下文。 不是 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(),
                        ),
                      ],
                    ),
                  ],
                )),
      ),

問題

如果在調用Scaffold.of(context).openDrawer() (或openEndDrawer() )時未使用正確的BuildContext ,則可能會出現此問題。

最簡單的解決方案

只需使用Builder小部件包裝任何調用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"),
    ),
  );
}

將 Drawer 分配給腳手架中的抽屜屬性。 使用 Builder 包裝您的特定小部件/按鈕(您希望在其單擊方法上打開抽屜的位置)。 在點擊屬性上使用以下方法:在此處輸入圖像描述Scaffold.of(context).openDrawer();

如果您有帶有操作按鈕的 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(
     ///...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM