【问题标题】:How to save complete recycler view data?如何保存完整的回收站视图数据?
【发布时间】:2021-07-12 18:06:36
【问题描述】:

说明

假设我有一个RecyclerView,它显示了内部存储中额外文件夹中的 50 张照片。考虑到这一点,那 50 张照片不会随时更改。因此,当用户启动应用程序时,它会从互联网上获取 50 张照片并保存在内部存储中。如果用户启动照片活动,则将运行从 extras 文件夹中获取这 50 张照片的循环。此循环将从内部存储中获取所有照片,并将它们的BUCKET_DISPLAY_NAMEextras 进行比较。如果两者相等,则只有它会显示在recyclerView

考虑到这种情况,我想将recyclerView statedata 保存在内部存储中。因此,当用户下次打开应用程序时,它不会获取所有照片,而是会直接加载带有已保存照片的 recyclerview。

获取方法

 public ArrayList<ImageModel> fetchImages() {
        uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        projection = new String[]{MediaStore.Images.Media._ID, MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
        cursor = activity.getApplicationContext().getContentResolver().query(uri, projection, null, null, null);
        column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID);
        arrayList.clear();          
        while (cursor.moveToNext()) {
            long mediaId = cursor.getLong(column_index_data);
            name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
            if (name.equals("extras")) {       
                Uri uriMedia = Uri.withAppendedPath(uri, "" + mediaId);
                ImageModel imageModel = new ImageModel();
                imageModel.setUri(uriMedia.toString());
                arrayList.add(imageModel);
            }
        }
        cursor.close();
        return arrayList;
    }

如果用户有很多照片而不是所需的 50 张照片,则在执行此方法时可能需要很长时间。

那么,

 arrayList = fetchImages();
adapter = new PhotosAdapter(requireActivity().getApplicationContext(), arrayList, getActivity(), this, this);
        recyclerView.setAdapter(adapter);

使用此方法将图像加载到recyclerView

那么,有没有办法保存加载的RecyclerViewRecyclerView Data

怀疑

https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.State

State 对象还可以保存任意数据,由资源 ID 标识。

我对任意数据不太了解,但是,如果它表示recyclerView's 数据,那么我该如何使用RecyclerView.State 对象来恢复recyclerView 中的数据?

注意

假设我可以在内部存储中保存任何类型的对象并将该对象加载到另一个相同类的对象中。

编辑 如答案中所述,无法存储已加载的 recyclerView。相反,需要缓存数据。由于缓存内存也在内部存储中,它迫使我的应用程序跳过帧,因为我正在我的应用程序的onCreateView() 中加载图像。我可以创建一个新线程,它将在后台处理它并且没有跳帧。但是,它会产生我不想要的眨眼效果。

【问题讨论】:

标签: java android android-recyclerview


【解决方案1】:

我不太了解任意数据,但如果这意味着 recyclerView 的数据然后我如何使用 RecyclerView.State 对象来 恢复recyclerView里面的数据?

不是,recyclerview 的 state 是指 recyclerview 的状态,比如它的垂直距离,view 相关数据等。list/data factory 不是由recyclerview 自己处理的,而是由Adapter 提供的。并且没有适配器的状态,这就是为什么您必须自己设法将数据加载到适配器中。

当您使用此方法时,如果用户有 除了需要的 50 张照片之外,还有很多照片。

对于您的特定情况,您可以使用缓存目录来更快、更轻松地访问您的照片,您只需检查缓存中是否存在照片,如果不存在,则下载,否则从缓存中获取。 Official docs

我想这就是你想要的。但是,如果您还想记住上次滚动位置,可以通过将上次滚动位置存储到 SharedPreferences 或类似实用程序中来实现。然后在加载数据后,您可以手动将 recyclerview 滚动到该位置。

【讨论】:

  • 缓存将被删除,android何时删除缓存,无法预测。我想确保只从内部存储中提取一次。除非用户命令它,否则我不想第二次运行循环。因此,保存的数据应该是永久性的。下载的照片已经在存储中,所以不需要互联网获取,但是,如果在缓存目录中找不到单个图像,则整个循环将运行以找到单个图像。
  • 是的,但是内部存储中的照片也可能被用户删除。我建议你使用 Glide 库来延迟加载来自互联网的图像,它会为你做所有事情,你不需要处理缓存或任何事情。您直接从视图持有者调用链接。这个库就是为此目的而构建的。
  • 照片存储在隐藏文件夹中。因此,用户无法删除它。我已经在使用 glide 来加载它。我想避免循环,因为循环是我的应用程序跳帧的原因。我想在 onCreate 中加载所有照片。但这样做会迫使我的应用跳过帧。即使使用滑翔库的缓存图像。我只是偶然发现了 RecyclerView.ViewCacheExtension。你知道那是什么吗?
  • 我确实创建了缓存目录并尝试过。性能是一样的。由于缓存目录也将在内部存储中创建,因此无济于事。
  • 如果您有每个图像的单独链接/路径,请使用 Glide,这将有助于这种情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多