首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >等待Navigator.pop忽略Navigator.pushReplacement

等待Navigator.pop忽略Navigator.pushReplacement
EN

Stack Overflow用户
提问于 2020-07-10 13:37:09
回答 1查看 2.1K关注 0票数 2

我有以下设置:

代码语言:javascript
运行
复制
class FirstScreen {
  // ...
  Future<void> doSomething() async {
    final bool isCool = await Navigator.of(context).pushNamed('/second-screen');
    print(isCool ? 'Cool.' : 'Not cool.');
  }
  // ...
}

class SecondScreen {
  // ...
  Future<void> replace() async {
    await Navigator.of(context).pushReplacementNamed('/third-screen');
  }
  // ...
}

class ThirdScreen {
  // ...
  Future<void> goBack() async {
    await Navigator.of(context).pop(true);
  }
  // ...
}

但是,这可能会崩溃,因为pushReplacement会触发await,而我的应用程序不会等到使用pop时再使用。

如何等待pop的值被返回?

更新:

这里的问题比我说的要复杂一些。

@Alok建议不要使用pop路由,而是按顺序执行路由,但是,这是我代码的一个非常琐碎的版本。

我现在有一个HomeScreen,它有一个嵌套的Navigator,可以推送到一个问题列表中。然后,使用Navigator.of(context, rootNavigator: true)导航到examLoadingScreen,等等(您可以在评论中了解到这一点)。

如果在考试结束时按下HomeScreen,就会丢失在上述嵌套Navigator中完成的所有导航。

在这种情况下,我非常需要pop。我有多种解决方案,比如pop链接,但它似乎不太好用,也不方便。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-10 14:24:27

参见,Zeswen,关于pushReplacementNamed上的文档。它指出:

通过推送名为routeName的路由,替换当前导航器的当前路由,该导航器最紧密地包围给定的上下文,然后在新路由完成动画化后将前一条路由进行处理。

您能看到吗,它清楚地提到,在您完成动画之后,它删除了以前的路径。

现在,您想要实现的是,或者Navigator.pop()值检索是如何工作的,当您从一个页面移动到另一个时,是必须的吗?

代码语言:javascript
运行
复制
//What you're doing with pushReplacementNamed
1 -> SeconPage => ThidPage
2 -> SecondPage [Removed] 
3 -> ThirdPage is trying to come to the previous page, that is SecondPage to return it's value, but SecondPage has been removed HENCE CRASHES!!

//What is needs to be done to use something like push() or pushNamed(), which used named route
1 -> SecondPage => ThirdPage
2 -> SecondPage is there in the stack
3 -> ThirdPage => SecondPage [Returns Value]

记住, pop()总是需要立即优先来接受它的值,而不是任何页面。因此,如果删除SecondPage,它总是会崩溃的。

现在,如果您想转到页面MainPage,或者在本例中是FirstPage。使用pushAndRemoveUntil。它基本上删除堆栈中的所有路由,然后转到页面。

解决方案:通过ResultPage将结果分数传递给MainPage。使MainPage也接受结果得分

代码语言:javascript
运行
复制
class ThirdScreen(){
  // ...
  Future<void> goBack() async {
    await Navigator.pushAndRemoveUntil(context, 
        MaterialPageRoute( builder: (context) => FirstPage(result: result),
        (_) => false
    );
  }
}

并相应地在FirstPage中执行操作,如果您有result != 0 || result != null,并将其显示给用户。如果这对你有用的话请告诉我。

更新的答案与一个最好的解决办法

我刚才补充了这个答案,因为我觉得以上的答案在将来也会有所帮助。

现在,我的想法是基本的,并且根据我可以得到的琐碎信息是可行的。

理论:根据的理论,pop()值只能被前辈immediate one访问。

溶液

代码语言:javascript
运行
复制
1. First Page -> Second Page
2. Second Page -> Third Page
3. Third Page -> Second Page with value

// Now following 3. step
1. Value check, if the value is true, pop immediately
2. Return the value to the first page
3. Print the value in the first page

只要跟随你的琐碎数据,我希望你能理解这个逻辑。在此之后,实现只是一个简单的工具。

代码语言:javascript
运行
复制
class FirstScreen {
  
  Future<void> doSomething() async {
    // We get the value from second page, which is technically passing 
    // the third page's value, and doesn't appear to us in UI
    // So serving the purpose
    final bool isCool = await Navigator.pushNamed(context, '/second-screen');
    print(isCool ? 'Cool.' : 'Not cool.');
  }
}

class SecondScreen {

  Future<void> replace() async {
    // No need of pushReplacementNamed, since we're are popping 
    // based upon our values, so it won't appear eventually
    // and pass the value as well for the First Page
    final bool value = await Navigator.pushNamed(context, '/third-screen');

    // Now we check, whether what value we got from third page,
    // If that is true, then immediately pop and return the value for first page
    if(value == true){
        Navigator.pop(context, value);
    }
  }
}

class ThirdScreen {
  // async not required for performing pop()
  // void is fine
  void goBack() {
    Navigator.pop(context, true);
  }
}

看看就行了。这个逻辑将帮助您达到目的,并且是安全和无错误的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62835504

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档