【发布时间】:2018-04-05 05:38:28
【问题描述】:
我正在玩一个简单的应用程序来学习 Flutter。这是 UI 的结构:
app -- MaterialApp -- HomeScreen (stateful)
|- ListView -- PlaceWidget (stateful)
|- ListTile
PlaceWidget 对象基本上构建并返回一个 ListTile;它唯一的额外职责是跟踪 favorited 状态并相应地构建 ListTile 的 UI。
源码为here,包括两个文件:
-
main.dart用于整个应用,并且 -
places.dart用于 http 请求
这是应用程序的行为方式:https://gfycat.com/FineBelovedLeafhopper
从表面上看,对象的状态似乎在滚动到视野之外时会丢失,但一些调试日志告诉我情况并非如此。
假设我最喜欢Oto Sushi,然后将其滚动到屏幕外,但保留指向状态对象的指针,该对象的favorited 状态仍将是true。然而,对象本身(属于_PlaceWidgetState 类)据报道为defunct, not mounted。
我无法再与该对象交互。如果我再次点击 Oto Sushi,它将创建一个新的状态对象并将该对象的 favorited 状态设置为 true,就像以前一样。
只要我不将 Oto Sushi 滚动到屏幕外,我就可以取消收藏它并且一切正常。
我设法找到了TextInputField 和ExpansionTile(例如this question)的类似问题,但我不知道如何将这些问题的解决方案转化为这个问题。
【问题讨论】:
-
它不在视野范围内时不会渲染,因此不存在并且没有要维护的状态。你需要自己维护状态。
-
@GünterZöchbauer 您能否进一步说明我应该如何实现这一目标?当它滚动回视图时,它的
build()函数会再次被调用吗?我意识到我可以简单地将变量保持在更高范围内以跟踪状态,我只是想知道是否有“好的代码”标准解决方案。 -
当然,
build将再次被调用。build通常也会在可见时被调用。我有一段时间没有对此进行调查,但如果它失去状态,initState也应该在它变得可见时再次渲染时被调用。 -
谢谢!我用
MyApp范围内的静态变量制作了一个肮脏的解决方案,以跟踪状态并检查build()方法中的状态;它现在工作正常。如果您对如何干净利落地提出建议,我将不胜感激。 -
medium.com/@mehmetf_71205/inheriting-widgets-b7ac56dbbeb1 你可能会感兴趣。 Redux 也经常用于维护状态,通常与 InheritedWidget 一起使用。
标签: scroll persistence state flutter