Scroll 调试帮助:flatterstatefulwidget不';t在滚动出视图后保持状态

Scroll 调试帮助:flatterstatefulwidget不';t在滚动出视图后保持状态,scroll,persistence,state,flutter,Scroll,Persistence,State,Flutter,我正在玩一个简单的应用程序来学习颤振。这是UI的结构: app--MaterialApp--HomeScreen(有状态) |-ListView—PlaceWidget(有状态) |-列表砖 PlaceWidget对象基本上构建并返回一个ListTile;它唯一的额外职责是跟踪偏好的状态,并相应地构建ListTile的UI 源代码是,包括两个文件: 整个应用程序的main.dart,以及 http请求的places.dart 这是应用程序的行为方式: 从表面上看,当滚动到视图之外时,对象

我正在玩一个简单的应用程序来学习颤振。这是UI的结构:

app--MaterialApp--HomeScreen(有状态)
|-ListView—PlaceWidget(有状态)
|-列表砖

PlaceWidget对象基本上构建并返回一个ListTile;它唯一的额外职责是跟踪
偏好的
状态,并相应地构建ListTile的UI

源代码是,包括两个文件:

  • 整个应用程序的
    main.dart
    ,以及
  • http请求的
    places.dart
这是应用程序的行为方式:


从表面上看,当滚动到视图之外时,对象的状态似乎丢失了,但是调试日志告诉我情况并非如此

假设我最喜欢的Oto Sushi然后将其从屏幕上滚动,但保留一个指向state对象的指针,该对象的
最喜欢的
状态仍然是
true
。但是,对象本身(属于类
\u PlaceWidgetState
)被报告为
已失效,未装入

我再也不能和那个物体互动了。如果我再次点击Oto Sushi,它将创建一个新的state对象,并像以前一样将该对象的
favorited
状态设置为
true

只要我不在屏幕外滚动Oto Sushi,我就可以不喜欢它,一切正常


我设法在
TextInputField
expansionfile
(例如)中找到了类似的问题,但我不知道如何将这些问题的解决方案转化为这个问题。

因此,撇开架构讨论不谈,问题的原因在于如何构造
状态
对象。通过将数据传递给构造函数,您可以确保每次重建小部件时,它们的状态都会重置

 class PlaceWidget extends StatefulWidget {
  @override
  _PlaceWidgetState createState() {
    return new _PlaceWidgetState(place, false); // woops, always unchecked
  }

  final Place place;
  PlaceWidget(this.place, {Key key}) : super(key: key);
}

class _PlaceWidgetState extends State<PlaceWidget> { ... }

现在,小部件不断被重建的原因是,在
列表视图中,屏幕外的小部件可能会被破坏-它是为非常大的列表设计的。为了防止出现这种情况,您还可以使用小部件。

它不在视图中时不会呈现,因此不存在,也没有要维护的状态。你需要自己维持这个状态。@GünterZöchbauer你能再澄清一点我应该如何做到这一点吗?当它卷回视图时,是否再次调用其
build()
函数?我意识到我可以简单地在更高的范围内保留一个变量来跟踪状态,我只是想知道是否有“好的代码”标准解决方案。当然,
build
将再次被调用<代码>构建
在可见时通常也会被调用。我已经有一段时间没有对此进行研究了,但是如果它失去了状态,
initState
也应该在它变为可见时再次渲染时调用。谢谢!我在
MyApp
范围内用一个静态变量编写了一个脏的解决方案,以跟踪状态并在
build()
方法中检查状态;它现在工作正常了。如果你有关于如何干净地做这件事的建议,我将不胜感激。你可能会感兴趣。Redux还经常用于维护状态,通常与InheritedWidget一起使用。为了将来参考,如果像我这样愚蠢的人遇到这个问题,完整的解决方案包括:-在
中本地跟踪状态\u PlaceWidgetState
,以及通过从
继承的widget
中拉入上下文来检索每个widget的状态。在Jonah的建议中,我们通过调用
inheritedWidget.of(context)
进一步更新
\u isChecked
,然后访问/更新
\u isChecked
应处于的状态
class _PlaceWidgetState extends State<PlaceWidget> {
  bool _isChecked = false; // only store state in State

  Widget build() {
   final Place place = widget.place;
   // build your stuff.
  }
}