在很长的 ListView 中记住滚动位置
Posted
技术标签:
【中文标题】在很长的 ListView 中记住滚动位置【英文标题】:Remember Scroll Position in very long ListView 【发布时间】:2020-10-19 11:32:57 【问题描述】:我的 Flutter 应用程序中显示了很长的项目列表,该列表由 API 填充,用户可以选择刷新列表以获取最新信息。
有什么方法可以知道用户在任何特定时间滚动到列表中的哪个位置?
然后当用户按下刷新时,我可以滚动回他们正在查看的列表中的最新位置?
我确实使用了这个“滚动位置列表”,但是当我滚动时,帧速率下降了很多......下降到 20 fps,如果可能的话,我想要一个平滑的 60 fps。 https://pub.flutter-io.cn/packages/scrollable_positioned_list
【问题讨论】:
更新,我已经设法通过优化列表本身的小部件来提高帧速率。看起来我可以从 scrollable_positioned_list 获得良好的性能,并且仍然能够使用它添加到 ListView.builder() 的额外功能 【参考方案1】:您是否尝试过使用 --release
运行您的应用程序?发布模式比调试模式具有更好的性能。而且我认为您可以使用普通的ListView.builder()
和ScrollController
https://api.flutter.dev/flutter/widgets/ScrollController-class.html 可能比pub.dev 上的可滚动列表具有更好的性能
【讨论】:
感谢您的评论,请参阅上面的评论。 ListView.builder() 不会让我可靠地知道顶部行中的数据是什么,这比物理滚动位置更需要。 你不能只使用列表来查看元素的顺序吗?【参考方案2】:我不知道 scrollable_positioned_list 包本身,但我认为您的实现不需要它。
首先,对于长列表,出于性能原因使用ListView.builder()
很重要。这只会加载当前在屏幕上可见的项目。这样可以节省很多资源(相当于android中的RecyclerView)。
要获取列表的位置,可以保存列表的滚动偏移值。您可以通过ScrollController
获取此信息。
这是我的示例代码:
import 'package:flutter/material.dart';
import 'package:preferences/preference_service.dart';
class MyListView extends StatefulWidget
final String _prefKey = 'listViewOffset';
@override
_MyListViewState createState() => _MyListViewState();
class _MyListViewState extends State<MyListView>
ScrollController controller;
@override
void initState()
controller = ScrollController(initialScrollOffset: PrefService.getDouble(widget.prefKey);
controller.addListener(()
PrefService.setDouble(widget.prefKey, controller.offset);
);
super.initState();
@override
Widget build(BuildContext context)
throw ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int position)
return ListTile(title: Text("Position $position"));
);
@override
void dispose()
controller.dispose(); // remove the listeners of our controller
super.dispose();
为了保存偏移量,我使用包preferences,但您也可以使用shared_preferences 包。
很遗憾,我没有机会在已完成的应用程序中测试我的代码,但我希望它能做到应有的效果。
【讨论】:
感谢您的评论。此选项在我的情况下实际上不起作用,因为我想知道数据列表中的哪个元素位于顶部。如果所有行的高度都相同,那么这会起作用,但我不能总是保证这一点。每次刷新时,项目的数量可能会发生变化,因此我需要的不是物理位置,而是行中的数据。以上是关于在很长的 ListView 中记住滚动位置的主要内容,如果未能解决你的问题,请参考以下文章