首页 > 解决方案 > 使用键在两个页面上重用小部件

问题描述

冗长的上下文,滚动到底部以获取特定问题:

我有一个带有自定义小部件 ( EntrySearch) 的页面,其中包含一个ListView和一个搜索栏。当用户单击列表视图中的某个项目时,我会推送一个具有相同列表视图的新页面和一个显示项目详细信息的面板。列表视图的项目从异步查询支持的 Stream 延迟加载(流暂停,直到用户滚动到到目前为止获取的元素的末尾)。每当用户在搜索栏中键入新字符串时,都会替换流。

我希望小部件在两个页面上具有相同的列表视图(元素、滚动位置等)和搜索栏状态。

我可以通过针对跨页面共享小部件状态的类似问题(例如这个)提出的许多状态管理解决方案中的任何一种来实现这一点。但是,因为我的 ListView 是由异步流以及大量其他状态支持的,所以这变成了缓存迄今为止获取的结果的总痛苦,创建一个从旧流停止的地方开始的新流(不能有两个 StreamBuilders由相同的非广播流支持)等等。我真的很想避免这种混乱的解决方案。

给我想要共享全局键的顶级小部件是一行(而不是〜50),并导致跨页面的共享状态。但是,当我推送新页面时,旧页面停留在小部件树中处于待机状态,因此我在小部件树中同时拥有两个具有相同全局键的小部件时收到错误消息。我可以在第一页上设置maintainStatefalse但是当我弹出第二页时,第一页显示为黑屏。

在那儿:

  1. 一种在两个页面上使用全局键小部件的方法,它们不会同时在树中
  2. 专门用于跨两个不同页面重用小部件的专用键
  3. 我没有想到的其他方法?

这是我的带有两个页面的小部件树。EntrySearch是我想在两个页面中重复使用的小部件。 小部件树

如果上述方法都不起作用,我将不得不使用传统的状态管理策略,该策略至少会更加冗长和容易出错一个数量级。

标签: flutterwidgetstate-managementstream-buildermaterialpageroute

解决方案


如果其他人遇到类似问题,这是我采用的解决方案:

我找不到使用密钥解决此问题的方法。我现在正在做的是我有一个类,其中包含我的自定义小部件需要自行构建的所有状态。每当我将路由推送到导航器时,我都会复制当前页面的状态对象以及所需的更改,然后将新状态添加到RouteSettings.argument字段中。然后,我可以使用ModalRoute.of(context).settings.arguments.

正如预期的那样,这个解决方案非常复杂和痛苦,我必须解决许多细微的错误。与简单地在两个页面之间保持相同的状态相比,它可以工作并且至少具有更理想的行为:当我弹出一个页面时,该状态也会弹出。这意味着用户可以ListView使用后退手势返回到之前的滚动位置。


推荐阅读