【问题标题】:How can I save and restore the scroll position of a Flutter ListView between app restarts?如何在应用重新启动之间保存和恢复 Flutter ListView 的滚动位置?
【发布时间】:2020-01-14 02:35:15
【问题描述】:

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

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

是否有内置方式(或插件)可以做到这一点?

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

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

【问题讨论】:

  • 为什么不在 Android 中的 onSaveInstanceState 中?
  • @Eugene shared_preferences 没有任何问题。我在问是否有一种内置方式(或插件)已经可以做到这一点。

标签: android listview flutter sharedpreferences scroll-position


【解决方案1】:

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

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

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

  • paused — 应用程序当前对用户不可见,不响应用户输入,并且在后台运行。就像Android中的onPause()
  • inactive — 应用程序处于非活动状态并且未接收用户输入。 (仅限 IOS)
  • resumed — 应用程序可见并响应用户输入。就像Android中的onPostResume()
  • suspending — 应用程序将暂时暂停。 (仅限 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');
  }
  ...

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2012-06-26
        • 2011-03-02
        • 2019-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-30
        • 2014-03-20
        相关资源
        最近更新 更多