Flutter 颤振:如何以编程方式打开抽屉

Flutter 颤振:如何以编程方式打开抽屉,flutter,dart,flutter-layout,Flutter,Dart,Flutter Layout,我想以编程方式打开抽屉而不是滑动它,如何禁用滑动功能(抽屉的触摸功能)空安全代码 使用GlobalKey: final GlobalKey _key=GlobalKey();//创建密钥 @凌驾 小部件构建(构建上下文){ 返回脚手架( key:\u key,//将密钥分配给Scaffold。 抽屉:抽屉(), 浮动操作按钮:浮动操作按钮( 按下时:()=>\u drawerKey.currentState!.openDrawer(),//Scaffold.of(context.openDra

我想以编程方式打开
抽屉
而不是滑动它,如何禁用滑动功能(抽屉的触摸功能)

空安全代码
  • 使用
    GlobalKey

    final GlobalKey _key=GlobalKey();//创建密钥
    @凌驾
    小部件构建(构建上下文){
    返回脚手架(
    key:\u key,//将密钥分配给Scaffold。
    抽屉:抽屉(),
    浮动操作按钮:浮动操作按钮(
    按下时:()=>\u drawerKey.currentState!.openDrawer(),//Scaffold.of(context.openDrawer(),//
    appBar:appBar(
    自动嵌入:false,
    标题:正文(
    “加密技术”,
    风格:
    TextStyle(fontFamily:“Poppins”,fontWeight:fontWeight.w600),
    ),
    行动:[
    图标按钮(
    图标:图标(图标菜单),
    已按下:(){
    if(_scaffoldKey.currentState.IsEndDrawerRopen){
    _scaffoldKey.currentState.openDrawer();
    }否则{
    _scaffoldKey.currentState.openEndDrawer();
    }
    },
    ),
    ],
    ),
    
  • 要禁用幻灯片打开功能,可以将Scaffold上的属性
    drawerEnableOpenDragesture
    设置为false
  • 
    进口“包装:颤振/材料.省道”;
    void main(){
    runApp(MyApp());
    }
    类MyApp扩展了无状态小部件{
    //此小部件是应用程序的根。
    @凌驾
    小部件构建(构建上下文){
    返回材料PP(
    家:脚手架(
    //这是为了防止默认的滑动行为
    Draggestore:错误,
    抽屉:抽屉(),
    appBar:appBar(
    前导:Builder(Builder:(context)=>//确保脚手架位于上下文中
    图标按钮(
    图标:图标(图标菜单),
    onPressed:()=>Scaffold.of(context.openDrawer())
    ),
    ),
    )
    )
    );
    }
    }
    
  • 要使用
    Scaffold.of(context)
    以编程方式打开抽屉,您必须确保(谢谢!)发出调用的上下文知道Scaffold

    drawer: Builder(
      builder: (BuildContext internalContext) {
        return _drawer(internalContext);
      },
    ),
    
    一个干净的方法是将按钮包装在生成器中。 我对答案进行了编辑,以包含一个最小的完整工作示例

    Scaffold是一个实现材质设计原则的小部件,因此要知道,要调用此方法,您需要
    导入“package:flatter/material.dart”;
    并且您的小部件需要有一个MaterialApp作为祖先


  • 与许多颤振问题一样,还有其他解决方案可以确保脚手架处于上下文中

    错误消息是颤振框架最好的特性之一,请允许我谦虚地建议您始终彻底阅读它们,并探索它们指向的文档

    例如,这是在适当的上下文之外调用openDrawer时收到的错误消息的一部分:

    Scaffold.of()使用不包含Scaffold的上下文调用。

    从传递给Scaffold.of()的上下文开始,找不到任何Scaffold祖先。当提供的上下文来自与构建函数实际创建要查找的Scaffold小部件相同的StatefulWidget时,通常会发生这种情况

    有几种方法可以避免此问题。最简单的方法是使用生成器获取脚手架“下”的上下文。有关此示例,请参阅Scaffold.of()的文档:

    一个更有效的解决方案是将构建函数拆分为多个小部件。这引入了一个新的上下文,您可以从中获取脚手架。在这个解决方案中,您将有一个外部小部件,该外部小部件创建由新的内部小部件的实例填充的脚手架,然后在这些内部小部件中使用Scaffold.of()

    一个不那么优雅但更方便的解决方案是为Scaffold分配一个GlobalKey,然后使用key.currentState属性来获取ScaffoldState,而不是使用Scaffold.of()函数


    下面是另一个从汉堡图标以编程方式打开抽屉而不使用Appbar的示例:-

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatefulWidget {
      @override
      State<StatefulWidget> createState() => MyAppState();
    }
    
    class MyAppState extends State<MyApp> {
      var scaffoldKey = GlobalKey<ScaffoldState>();
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            key: scaffoldKey,
            drawer: new Drawer(
              child: new ListView(
                padding: EdgeInsets.zero,
                children: <Widget>[
                  DrawerHeader(
                    child: Text('Drawer Header'),
                    decoration: BoxDecoration(
                      color: Colors.blue,
                    ),
                  ),
                  ListTile(
                    title: Text('Item 1'),
                    onTap: () {
                      //Do some stuff here
                      //Closing programmatically - very less practical use
                      scaffoldKey.currentState.openEndDrawer();
                    },
                  )
                ],
              ),
            ),
            body: Stack(
              children: <Widget>[
                new Center(
                    child: new Column(
                  children: <Widget>[],
                )),
                Positioned(
                  left: 10,
                  top: 20,
                  child: IconButton(
                    icon: Icon(Icons.menu),
                    onPressed: () => scaffoldKey.currentState.openDrawer(),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    导入“包装:颤振/材料.省道”;
    void main()=>runApp(MyApp());
    类MyApp扩展了StatefulWidget{
    @凌驾
    State createState()=>MyAppState();
    }
    类MyAppState扩展了状态{
    var scaffoldKey=GlobalKey();
    @凌驾
    小部件构建(构建上下文){
    返回新材料PP(
    debugShowCheckedModeBanner:false,
    家:脚手架(
    钥匙:脚手架钥匙,
    抽屉:新抽屉(
    子:新列表视图(
    填充:EdgeInsets.zero,
    儿童:[
    抽屉阅读器(
    子项:文本(“抽屉标题”),
    装饰:盒子装饰(
    颜色:颜色,蓝色,
    ),
    ),
    列表砖(
    标题:文本(“项目1”),
    onTap:(){
    //在这里做些事情
    //以编程方式关闭-非常不实用
    scaffoldKey.currentState.openEndDrawer();
    },
    )
    ],
    ),
    ),
    主体:堆栈(
    儿童:[
    新中心(
    子:新列(
    儿童:[],
    )),
    定位(
    左:10,,
    前20名,
    孩子:我的钮扣(
    图标:图标(图标菜单),
    按下时:()=>scaffoldKey.currentState.openDrawer(),
    ),
    ),
    ],
    ),
    ),
    );
    }
    }
    
    调用Scaffold.of不起作用,因为上下文不包含Scaffold。上面的一些解决方案忽略了这一点,其他解决方案使用了GlobalKey。我认为最干净的解决方案是在生成器中包装按钮:

    脚手架(
    DroperEnableOpenDragesture:false,//防止用户
    
    drawer: Builder(
      builder: (BuildContext internalContext) {
        return _drawer(internalContext);
      },
    ),
    
    class SampleAppPage extends StatelessWidget {
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          home: new Scaffold(
            appBar: _appBar(context),
            drawer: new Builder(
              builder: (BuildContext internalContext) {
                return _drawer(internalContext);
              },
            ),
            body: new Builder(
              builder: (BuildContext internalContext) {
                return _body(internalContext);
              },
            ),
          ),
        );
      }
    
      Widget _appBar(BuildContext context) {
        return new AppBar(
          title: new Text('Drawer example'),
        );
      }
    
      Widget _drawer(BuildContext context) {
        return new Center(
          child: new RaisedButton(
            child: new Text('Close drawer'),
            onPressed: () => Navigator.of(context).pop(),
          ),
        );
      }
    
      Widget _body(BuildContext context) {
        return new Column(
          children: <Widget>[
            new RaisedButton(
              child: new Text('Open via Scaffold context'),
              onPressed: () => Scaffold.of(context).openDrawer(),
            ),
          ],
        );
      }
    }