颤振:如何避免在ListView.builder中自动滚动

时间:2020-09-24 16:23:48

标签: flutter listview

我正在构建一个聊天应用程序,并且已经到达创建实际聊天界面的那一部分。我决定使用ListView.builder()构造函数,因为我正在处理大量数据(消息)。布局以及我的代码通常看起来像this

我想随时保留滚动位置,除非用户明确滚动。这是第一个问题:出现软键盘或输入字段的大小改变时,我希望消息区域的底部保持可见状态,而较旧(即上方)的消息则被推出屏幕。您知道它在Messenger中的工作方式等。但是,它并不是那样工作的。较旧的消息保持可见,而较新的消息将被推送。

为此,我尝试将reverse参数设置为true。虽然确实解决了上述问题,但它创造了一个新的问题。每当添加新消息时(由于它是“撤消的”,我必须在消息列表之前添加),整个消息区域似乎都在“跳转”。我相信,由于ListView被颠倒,索引为0的项目始终是最新消息。

但是,我不喜欢这种行为。对于用户来说,这似乎并不直观,他们希望向下滚动到最新消息,或者看到一个浮动的UI元素,指示有新消息。

问题#1:我可以以某种方式禁用/更改反向列表的上述行为吗?我正在考虑一个回调,该回调计算“旧”偏移量,并在添加新消息时立即滚动到该位置。不确定是否有可能或是否适合该模式。

问题2:我虽然不使用反向列表,但添加了SizeChangedLayoutNotifier之类的内容,听着ListView的大小变化,并相应地滚动到了位置。不过,这看起来也很骇人。

通常来说,我想实现类似Messenger的行为(或者实际上是任何其他类似的应用程序)。打开软件键盘应“推送”消息,并且当收到新消息时,不应有任何跳转或自动滚动。


更新#1:找到了一种解决方法,但我不希望这样做。每当添加项目时,我都会获得position.maxScrollExtent的{​​{1}}值,然后,在更新状态后,我将获得新值。从旧值中减去新值,然后从当前偏移量中减去差值,最后ScrollController。还有voilà,我们的信息是一样的。但是,这有多个缺点:

  • 根据这种解决方法的性质,它很容易实现。您必须知道新的最高滚动范围将用于计算差异,因为您无法知道新消息的持续时间以及气泡的高度。
  • 种族状况?您必须等待一段任意时间(因为缺少更好的方法,是否需要任何接受者?)才能看到值更新。它可以在模拟器中正常运行,但是可以在用户的​​设备上运行吗?
  • 这不是声明性/反应性的。在我的本地示例中,我知道何时添加项目/消息。但是,在使用流时,每次发生这种情况时我都需要一个侦听器来捕获,这会令人头疼。

由于上述原因,我决定不使用此替代方法。


谢谢。

0 个答案:

没有答案