【问题标题】:Flutter Drawer Widget - change Scaffold.body contentFlutter Drawer Widget - 更改 Scaffold.body 内容
【发布时间】:2018-06-05 19:26:39
【问题描述】:

使用 Flutter Scaffold.Drawer 时 - 是否可以让 Drawer 中的链接更改页面上的内容(Scaffold.body)?

类似于让导航抽屉中的链接更改 Android 中的 Fragment。

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    这是一个简单而有效的方法来完成这个完整的例子

    class _MyPageState extends State<MyPage> {
      Widget bodyWidget;
    
      Widget drawer() {
        return
      }
    
      Widget bodyFirst() {
        return Container(
            color: Colors.green, child: Center(child: Text("First Page")));
      }
    
      Widget bodySecond() {
        return Container(
            color: Colors.limeAccent, child: Center(child: Text("Second Page")));
      }
    
      Widget bodyThird() {
        return Container(
            color: Colors.lightBlueAccent,
            child: Center(child: Text("Third Page")));
      }
      
      @override
      void initState() {
        super.initState();
        bodyWidget = bodyFirst();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          drawer: drawer(),
          appBar: AppBar(title: Text("My App")),
          body: bodyWidget,
        );
      }
    }
    

    【讨论】:

    • 只是我还是您的示例缺少执行交换的代码?
    【解决方案2】:

    您可以将它用于脚手架的主体:

            body: _getDrawerItemWidget(_selectedDrawerIndex));
    

    然后在主类或状态类中这样做:

    class HomePageState extends State<HomePage> {
      int _selectedDrawerIndex = 0;
    
      _getDrawerItemWidget(int pos) {
        switch (pos) {
          case 0:
            return new MainFragment();
          case 1:
              return new CardMgmt();
    }
    }
    }
    

    CardMgmt 和 switch case 中的其他类都有自己的构建方法,该方法将返回一个 Widget,并将其放置在脚手架的主体中。它们也可以在同一个 dart 文件甚至另一个文件中。
    但是我还有一个问题:
    如果我们在另一个类(如 CardMgmt)中有一个按钮而不是抽屉项,我们希望它返回一个小部件并更新页面,该怎么办?

    【讨论】:

    • 我也遇到了,你找到解决办法了吗?
    【解决方案3】:

    这是 Aziza 提供的一个非常好的解决方案!谢谢你。有用!我只想补充一点,它也可以通过用小部件状态替换它来为整个身体工作:

    ...
    class _TestPageState extends State<TestPage> {
      String text = "Initial Text";
      Widget widgetForBody = SomeWidgetFromClass();
      ...
      ...
            children: <Widget>[
              new Container(child: new DrawerHeader(child: new Container())),
              new Container (
                child: new Column(
                    children: <Widget>[
                      new ListTile(leading: new Icon(Icons.info),
                          onTap:(){
                              setState((){
                                widgetForBody = AnotherWidgetFromClass();
                              });
                          }
                      ),
                      new ListTile(leading: new Icon(Icons.save),
                          onTap:(){
                            setState((){
                              widgetForBody = YetAnotherWidgetFromClass();
                            });
                          }
                      ),
    ...
    

    【讨论】:

      【解决方案4】:

      您可以通过与您的Drawer 项目进行交互来简单地更改您感兴趣的内容的state,如下所示:

      这里是这个例子的相关代码:

      class TestPage extends StatefulWidget {
        @override
        _TestPageState createState() => new _TestPageState();
      }
      
      class _TestPageState extends State<TestPage> {
        String text = "Initial Text";
        @override
        Widget build(BuildContext context) {
          return new Scaffold(
              drawer: new Drawer(
                child: new ListView(
                  children: <Widget>[
                    new Container(child: new DrawerHeader(child: new Container())),
                    new Container (
                      child: new Column(
                          children: <Widget>[
                            new ListTile(leading: new Icon(Icons.info),
                                onTap:(){
                                    setState((){
                                      text = "info pressed";
                                    });
                                }
                            ),
                            new ListTile(leading: new Icon(Icons.save),
                                onTap:(){
                                  setState((){
                                    text = "save pressed";
                                  });
                                }
                            ),
                            new ListTile(leading: new Icon(Icons.settings),
                                onTap:(){
                                  setState((){
                                    text = "settings pressed";
                                  });
                                }
                            ),
      
                          ]
                      ),
                    )
                  ],
                ),
              ),
              appBar: new AppBar(title: new Text("Test Page"),),
              body: new Center(child: new Text((text)),
              ));
        }
      }
      

      【讨论】:

      • 刚开始学习 Flutter,正是我想要的。我在互联网上找到的所有教程都只是创建新的小部件,将所有打开的 Scaffold 复制为一个新的 Activity。谢谢。
      • 您可能希望通过在每个 onTap 属性上调用 Navigator.of(context).pop(); 来自动关闭抽屉而不是手动关闭抽屉来增强此功能
      • 非常感谢。我想知道是否可以使用导航器来实现这一点?
      • 是的,只需在每个onTap 中使用Navigator.of(context).pop(); 即可自动关闭抽屉。
      • 我理解,我的意思是屏幕变化,通过添加导航器作为body
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-14
      • 1970-01-01
      • 1970-01-01
      • 2019-09-27
      • 1970-01-01
      • 2023-04-09
      • 2021-12-23
      相关资源
      最近更新 更多