我正在尝试创建一个可在我的应用程序中的所有页面访问的统一抽屉.如何在所有这些页面中保持它,而不必在每个dart文件中重新创建我的自定义Drawer小部件?
这有几个不同的选择.最基本的是希望你已经完成的事情,但无论如何我会列出它:
1:为您的抽屉创建一个班级
您的小部件应该是自己的有状态或无状态小部件.这样,您每次都必须实例化它.
class MyDrawer extends StatelessWidget { @override Widget build(BuildContext context) { return Drawer(...); } }
然后在每个页面中使用它时:
Scaffold( drawer: MyDrawer(...), ... )
我希望你已经这样做了; 如果不是,你应该是.类的构建函数不应该太大,否则会导致性能不佳并且难以维护代码; 从长远来看,将事物分成逻辑单元将对您有所帮助.
2:为您的脚手架创建一个类
如果必须在每个页面的脚手架中包含相同的抽屉仍然是太多的代码,您可以改为使用封装您的脚手架的类.它实际上会为您实际使用的每个脚手架输入提供输入.
class MyScaffold extends StatelessWidget { final Widget body; MyScaffold({this.body}); @override Widget build(BuildContext context) { return Scaffold( body: body, drawer: MyDrawer(...), ); } }
然后在您的代码中使用Scaffold,而不是使用MyScaffold(但请将其命名为更好的= D).
3:多层脚手架
我只是采用这种方式完成它,我不推荐它.话虽这么说,有些事情你无法在flutter的正常工作流程中工作,你可以这样做 - 例如,如果你想要一个自定义动画,当用户点击抽屉中的不同项目时.
基本上,在这种情况下你要做的就是在你的MaterialApp或Navigator之外有一个Scaffold(我相信这也意味着你必须在那之外有另一个Navigator,但我不是100%肯定).您可以让导航栏外的脚手架显示抽屉,而另一个(在导航中的每个页面上)将执行您需要它做的任何其他操作.有一些警告 - 你必须确保你得到正确的脚手架(即Scaffold.of(context)
它本身不会削减它 - 你必须得到第一个脚手架的上下文并用它来找到更高级别的脚手架) ,你可能需要将一个GlobalKey(较低级别的脚手架)传递给Drawer,以便它可以实际更改其中的页面.
正如我所说的,我不推荐这种方法,所以我不打算进一步详细说明,而是将它留作读者的练习,如果他们想要去那个兔子洞!
rmtmckenzie是非常正确的。
尽管如果您对多功能支架解决方案感到好奇,这可能比您想象的要优雅。
要在所有页面之间共享抽屉,我们可以builder
在MaterialApp
实例中添加一个。这将实例化Scaffold
下面Navigator
但高于所有路线的a。
MaterialApp( title: 'Flutter Demo', builder: (context, child) { return Scaffold( drawer: MyDrawer(), body: child, ); }, home: MyHome() )
在页面内部,您可以像平常一样Scaffold
不受限制地实例化另一个。
然后,您可以做任何插件的下面显示的共享抽屉下 MaterialApp
:
final ScaffoldState scaffoldState = context.rootAncestorStateOfType(TypeMatcher()); scaffoldState.openDrawer();
您可以将其提取为一个好帮手的代码:
class RootScaffold { static openDrawer(BuildContext context) { final ScaffoldState scaffoldState = context.rootAncestorStateOfType(TypeMatcher()); scaffoldState.openDrawer(); } }
然后重复使用 RootScaffold.openDrawer(context)
除了@RémiRousselet答案
MaterialApp( title: 'Flutter Demo', builder: (context, child) { return Scaffold( drawer: MyDrawer(), body: child, ); }, home: MyHome() )
对于根抽屉中的“导航”,如果使用Navigator.of(context) // push or pop
它将引发错误,并且必须使用子窗口小部件导航到其他页面
像那样
(child.key as GlobalKey).currentState // push or pop
Github中的演示项目