【问题标题】:Return data when a screen is closed关闭屏幕时返回数据
【发布时间】:2022-10-22 08:26:00
【问题描述】:

我有几个子屏幕让用户可以选择保存一些数据。当该屏幕关闭时,我希望推动子屏幕的父屏幕知道是否保存了数据。子屏幕保持didSave 标志并在保存数据时设置为true。

子屏幕有几种关闭方式:

  • 硬件/软件后退按钮。
  • AppBar 上的关闭按钮。
  • 屏幕本身的按钮。

我可以使用Navigator.pop(context, didSave) 处理第三种情况,并在父级中使用final didSave = await Navigator.push<bool>(context, myRoute) 捕获didSave 标志。

但是,对于前两种情况,结果显然是null。

我已经查看了WillPopScope,但这仅用于确定是否应该关闭屏幕。我似乎无法设置要为推送调用返回的任何数据。

我还研究了将父屏幕包装在 Provider 中,它可以在其中侦听 didSave 状态,但是在发出时会立即触发,这对于我的用例来说是不可取的。我只想在关闭子屏幕时而不是在保存数据时采取行动。

如果发生了保存操作,我可能会使用WillPopScope 并在那里发出一个事件,但如果可用,我想要一个更简单的解决方案。

有没有我想念的方法?

谢谢!

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    正如您所说,Provider 将收听didSave,这不适合您的情况,您可以只使用一个简单的inheritedWidget:

    像这样包装父母:

    InheritedExampleWidget(
    didSave: false,
    child: Parent(),
    ),
    

    您需要将设置器设置为didSave 然后在小部件树上的上升小部件上,您可以:

    InheritedExampleWidget.of(context).didSave = true;
    

    这不会立即触发它,Provider 包解决了这个问题。 那么你可以随心所欲地管理状态

    【讨论】:

      【解决方案2】:

      您是否尝试使用状态管理创建变量?在用户来自子屏幕后,还有一种推送方法可以执行任务。因此,当他们来时,您可以检查使用是否已保存数据。

      对于 EG:

      saved = false; //State management variable
      
      //We are pushing on another screen.
      Navigator.of(context).push(
                            MaterialPageRoute(
                              builder: (BuildContext context) =>
                                  new ScreenName(),
                            ),
                          ).then((val) {
      //This part with work when user popped the screen on which we have pushed
                            if (!saved) {//Do Something when not saved}
                          });
      

      尝试上面的代码,如果您遇到任何错误或遇到任何问题,请告诉我。

      【讨论】:

        【解决方案3】:

        当您使用StatefulWidget 推送新路由时,它将具有从createState 开始的生命周期,当窗口小部件不在窗口小部件树上时(当我们弹出时),将调用dispose 方法。

        那些弹出路线的情况:

        • 硬件/软件后退按钮。
        • AppBar 上的关闭按钮。
        • 屏幕本身的按钮。

        将触发 dispose 方法执行。 所以你可以把你想要的逻辑放在里面。

        例子 :

        class classTest {
          bool didSave = false;
        }
        

        然后在要推送屏幕的属性上将其设置为classTest 的didSave,例如:

        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => const YourRouteWidget(didSave: classTest.didSave,
          ),
          ),
        );
        

        在那一点上它是false,然后当用户完成使用屏幕,返回任何弹出路线的国王(使用Navigator.pop(context),或使用后退按钮......),将调用dispose方法,所以你可以 :

           void dispose() {
           if(/* your conditions*/ ) {
           classTest.didSave = true;
           }
            super.dispose();
          }
        

        它将以true 值返回到父页面。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-12-15
          • 2021-08-23
          • 1970-01-01
          • 1970-01-01
          • 2020-02-15
          • 1970-01-01
          • 1970-01-01
          • 2018-07-10
          相关资源
          最近更新 更多