2

我想保留 ListView 的滚动位置,以便在应用程序重新启动之间恢复。

所以我想它应该使用类似的东西保存在磁盘上shared_preferences(在 iOS 上的 NSUserDefaults 和 Android 上的 SharedPreferences 中)

有没有内置的方式(或插件)来做到这一点?

如果我必须手动完成,我应该什么时候保存滚动位置?(在原生 Android 应用程序中,我会在onPauseActivity 生命周期方法中执行此操作。)

我进行了很多搜索,但似乎找不到任何显示如何保存和恢复 ListView 滚动位置的帖子或示例代码。

4

3 回答 3

1

如果我必须手动完成,我应该什么时候保存滚动位置?(在原生 Android 应用程序中,我会在 onPause Activity 生命周期方法中执行此操作。)

您可以使用 mixin WidgetsBindingObserver通过侦听AppLifecycleState来检测您的应用程序何时进入后台以及何时进入前台

可观察的生命周期事件是:

  • paused — 应用程序当前对用户不可见,不响应用户输入,并且在后台运行。就像onPause()在 Android中一样
  • 非活动 - 应用程序处于非活动状态并且未接收用户输入。(仅限IOS)
  • resumed — 应用程序可见并响应用户输入。就像onPostResume()在 Android中一样
  • 暂停 - 应用程序将暂时暂停。(仅限安卓)

在示例中,我保存日期而不是滚动位置

class _TestPageState extends State<TestPage> with WidgetsBindingObserver {

  SharedPreferences prefs;

  @override
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print('state = $state'); // resumed, paused, inactive, suspending
    if (state == AppLifecycleState.paused) {
        prefs.setString('date', DateTime.now().toIso8601String());
    }
  }

  _TestPageState() {
    initPrefs();
  }

  void initPrefs() async {
    prefs = await SharedPreferences.getInstance();
    print(prefs.getString('date') ?? 'no date');
  }
  ...
于 2019-09-12T09:51:56.460 回答
1

我们现在对 Flutter 中的状态恢复提供了开箱即用的支持。检查小部件restorationId内的属性ScrollView。查看此链接以了解如何在 Flutter 中实现恢复。 https://dev.to/pedromassango/what-is-state-restoration-and-how-to-use-it-in-flutter-5blm

于 2021-01-16T18:51:50.033 回答
0

正如您在问题中所说 - 使用https://pub.dev/packages/shared_preferences是最好的选择,因为它利用了处理此类内容的本机方式 -SharedPreferences适用于 Android 和NSUserDefaultsiO。在 Android 中的新方法它PersistentBundle也可以在颤振中使用,但没有适用于 iO 的模拟。您也可以使用各种数据库和文件存储,但在这种情况下它会是多余的。

在移动设备上存储滚动状态始终是一项手动任务——没有开箱即用的快捷方式——所以只有手工制作的东西或库。

您可以将有状态小部件的整个状态存储在那里,然后将其作为一个整体恢复。

于 2019-09-12T09:24:25.950 回答