我想以编程方式打开Drawer,而不是通过滑动,如何禁用滑动功能(抽屉的触摸功能)
Drawer
6kkfgxo01#
GlobalKey
final GlobalKey<ScaffoldState> _key = GlobalKey(); // Create a key @override Widget build(BuildContext context) { return Scaffold( key: _key, // Assign the key to Scaffold. drawer: Drawer(), floatingActionButton: FloatingActionButton( onPressed: () => _key.currentState!.openDrawer(), // <-- Opens drawer ), ); }
Builder
@override Widget build(BuildContext context) { return Scaffold( drawer: Drawer(), floatingActionButton: Builder(builder: (context) { return FloatingActionButton( onPressed: () => Scaffold.of(context).openDrawer(), // <-- Opens drawer. ); }), ); }
如果要禁用使用拖动手势打开Drawer,可以设置
Scaffold( drawerEnableOpenDragGesture: false // above code ... )
nbewdwxp2#
1.要禁用幻灯片打开功能,可以将Scaffold上的属性drawerEnableOpenDragGesture设置为false。
drawerEnableOpenDragGesture
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( home: Scaffold( // this to prevent the default sliding behaviour drawerEnableOpenDragGesture: false, drawer: Drawer(), appBar: AppBar( leading: Builder(builder: (context) => // Ensure Scaffold is in context IconButton( icon: Icon(Icons.menu), onPressed: () => Scaffold.of(context).openDrawer() ), ), ) ) ); } }
1.要使用Scaffold.of(context)以编程方式打开抽屉,您必须确保(感谢Krolaw!)在其中进行调用的上下文知道Scaffold。一个简洁的方法是将按钮 Package 在一个构建器中。我已经编辑了答案,包括了一个最小的完整的工作示例。Scaffold是一个实现材料设计原则的小部件,因此要知道,要能够调用此方法,您需要import 'package:flutter/material.dart';,并且您的小部件需要有一个MaterialApp作为祖先。Codepen demo与许多Flutter一样,还有其他解决方案可以确保Scaffold符合上下文。错误消息是IMO flutter框架最好的特性之一,请允许我谦虚地建议您始终彻底阅读它们,并探索它们所指向的文档。例如,如果在正确的上下文之外调用openDrawer,则会收到错误消息的一部分:
Scaffold.of(context)
import 'package:flutter/material.dart';
使用不包含Scaffold的上下文调用了Scaffold.of()。
从传递给Scaffold.of()的上下文开始,找不到任何Scaffold祖先。当提供的上下文与其构建函数实际创建所查找的Scaffold小部件的上下文来自同一StatefulWidget时,通常会发生这种情况。有几种方法可以避免这个问题。最简单的方法是使用构建器来获取一个在Scaffold“下面”的上下文。有关这个方法的示例,请参阅Scaffold.of()的文档:https://api.flutter.dev/flutter/material/Scaffold/of.html一个更有效的解决方案是将构建函数拆分为几个小部件。这引入了一个新的上下文,您可以从中获取Scaffold。在这个解决方案中,您将有一个外部小部件,它创建由新的内部小部件的示例填充的Scaffold,然后在这些内部小部件中,您将使用Scaffold.of()。一个不太优雅但更方便的解决方案是为Scaffold分配一个GlobalKey,然后使用key.currentState属性获取ScaffoldState,而不是使用Scaffold.of()函数。
roejwanj3#
调用Scaffold.of不起作用,因为上下文不包含Scaffold。上面的一些解决方案忽略了这一点,另一些则使用了GlobalKey。我相信最干净的解决方案是将按钮 Package 在Builder中:
Scaffold( drawerEnableOpenDragGesture: false, // Prevent user sliding open appBar: AppBar( automaticallyImplyLeading: false, title: Text("Some Title"), actions: [ Builder(builder: (context) => // Ensure Scaffold is in context IconButton( icon: Icon(Icons.settings), onPressed: () => Scaffold.of(context).openDrawer() )), ], ), // TODO ... )
nlejzf6q4#
下面是另一个通过编程方式从汉堡包图标打开抽屉的例子,并且不使用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(), ), ), ], ), ), ); } }
zwghvu4y5#
appBar: AppBar( automaticallyImplyLeading: false, title: Text( "Infilon Technologies", style: TextStyle(fontFamily: "Poppins", fontWeight: FontWeight.w600), ), actions: <Widget>[ IconButton( icon: Icon(Icons.menu), onPressed: () { if (_scaffoldKey.currentState.isEndDrawerOpen) { _scaffoldKey.currentState.openDrawer(); } else { _scaffoldKey.currentState.openEndDrawer(); } }, ), ], ),
7hiiyaii6#
如果在Scaffold中使用endDrawer(从右到左),则应用途:
endDrawer
Scaffold.of(context).openEndDrawer();
如果在Scaffold中使用drawer(从左到右),则应用途:
drawer
Scaffold.of(context).openDrawer();
2sbarzqh7#
你可以用这个完美的方法来打开抽屉它的工作与零安全模块以上Flutter2.12
class DashBoardScreen extends StatefulWidget { final String? screen; const DashBoardScreen(this.screen, {super.key}); @override State<DashBoardScreen> createState() => _DashBoardScreenState(); } class _DashBoardScreenState extends State<DashBoardScreen> { DashBoardScreenController controller = Get.put(getIt<DashBoardScreenController>()); @override Widget build(BuildContext context) { controller.scaffoldKey = GlobalKey<ScaffoldState>(); return Obx(() => Scaffold( key: controller.scaffoldKey, onDrawerChanged: (isOpened) { if (!isOpened) { setState(() {}); } }, appBar: AppBar( title: const Text("Test drawer App"), actions: const [ const Padding( padding: EdgeInsets.only(right: 20), child: Icon(Icons.search)) ], leading: UnconstrainedBox( child: GestureDetector( onTap: () { controller.scaffoldKey.currentState!.openDrawer(); }, child: const AbsorbPointer( absorbing: true, child: SizedBox( height: 50, child: CircleAvatar( backgroundImage: CachedNetworkImageProvider( "https://cdn.pixabay.com/photo/2014/07/09/10/04/man-388104_960_720.jpg", )), ), ), ), ), ), drawerEdgeDragWidth: kIsWeb ? MediaQuery.of(context).size.width * 0.2 : null, drawer: Drawer( key: controller.scaffoldKey, child: ListView( children: [ DropdownMenuItem(onTap: () {}, child: const Text("Add Anime")) ], )), body: widget.screen == StringVariables.ADD_ANIME ? AddAnimeFragment(widget.screen!) : Container(), bottomNavigationBar: BottomNavigationBar( items: const <BottomNavigationBarItem>[ BottomNavigationBarItem( icon: Icon(Icons.home), label: 'Add Anime', ), BottomNavigationBarItem( icon: Icon(Icons.business), label: 'Favourite', ), BottomNavigationBarItem( icon: Icon(Icons.settings), label: 'Settings', ), ], currentIndex: controller.bottomSheetIndex.value, selectedItemColor: ColorName.primaryColor, onTap: (s) { controller.bottomSheetIndex.value = s; }, ), )); } }
cyej8jka8#
只需执行以下步骤在类中创建一个变量,如下所示
var scaffoldKey = GlobalKey<ScaffoldState>();
然后像这样在脚手架上使用这把钥匙
Scaffold( key: scaffoldKey, appBar: AppBar( automaticallyImplyLeading: false, leading: IconButton( onPressed: () { scaffoldKey.currentState?.openDrawer(); }, icon: Icon( Icons.menu, color: ExtraColors.PRIMARY_800, )), title: Text( '${AppStrings.appName}', ), centerTitle: true, ), )
8条答案
按热度按时间6kkfgxo01#
空安全代码
GlobalKey
:Builder
:如果要禁用使用拖动手势打开
Drawer
,可以设置nbewdwxp2#
1.要禁用幻灯片打开功能,可以将Scaffold上的属性
drawerEnableOpenDragGesture
设置为false。1.要使用
Scaffold.of(context)
以编程方式打开抽屉,您必须确保(感谢Krolaw!)在其中进行调用的上下文知道Scaffold。一个简洁的方法是将按钮 Package 在一个构建器中。我已经编辑了答案,包括了一个最小的完整的工作示例。
Scaffold是一个实现材料设计原则的小部件,因此要知道,要能够调用此方法,您需要
import 'package:flutter/material.dart';
,并且您的小部件需要有一个MaterialApp作为祖先。Codepen demo
与许多Flutter一样,还有其他解决方案可以确保Scaffold符合上下文。
错误消息是IMO flutter框架最好的特性之一,请允许我谦虚地建议您始终彻底阅读它们,并探索它们所指向的文档。
例如,如果在正确的上下文之外调用openDrawer,则会收到错误消息的一部分:
使用不包含Scaffold的上下文调用了Scaffold.of()。
从传递给Scaffold.of()的上下文开始,找不到任何Scaffold祖先。当提供的上下文与其构建函数实际创建所查找的Scaffold小部件的上下文来自同一StatefulWidget时,通常会发生这种情况。
有几种方法可以避免这个问题。最简单的方法是使用构建器来获取一个在Scaffold“下面”的上下文。有关这个方法的示例,请参阅Scaffold.of()的文档:https://api.flutter.dev/flutter/material/Scaffold/of.html
一个更有效的解决方案是将构建函数拆分为几个小部件。这引入了一个新的上下文,您可以从中获取Scaffold。在这个解决方案中,您将有一个外部小部件,它创建由新的内部小部件的示例填充的Scaffold,然后在这些内部小部件中,您将使用Scaffold.of()。
一个不太优雅但更方便的解决方案是为Scaffold分配一个GlobalKey,然后使用key.currentState属性获取ScaffoldState,而不是使用Scaffold.of()函数。
roejwanj3#
调用Scaffold.of不起作用,因为上下文不包含Scaffold。上面的一些解决方案忽略了这一点,另一些则使用了GlobalKey。我相信最干净的解决方案是将按钮 Package 在Builder中:
nlejzf6q4#
下面是另一个通过编程方式从汉堡包图标打开抽屉的例子,并且不使用Appbar:-
zwghvu4y5#
7hiiyaii6#
如果在Scaffold中使用
endDrawer
(从右到左),则应用途:如果在Scaffold中使用
drawer
(从左到右),则应用途:2sbarzqh7#
你可以用这个完美的方法来打开抽屉它的工作与零安全模块以上Flutter2.12
cyej8jka8#
只需执行以下步骤
在类中创建一个变量,如下所示
然后像这样在脚手架上使用这把钥匙