Android RecyclerView数据更新失败:异步操作后视图未刷新怎么办?

Android RecyclerView数据更新失败:异步操作后视图未刷新怎么办?

android RecyclerView 数据更新难题:异步操作后的视图刷新问题

在Android开发中,使用RecyclerView展示数据时,常常会遇到数据更新后界面却无法同步刷新。本文将通过一个实际案例,分析导致RecyclerView视图更新失败的常见原因,并提供有效的解决方案。

问题描述: 开发者使用RecyclerView展示用户数据,网络请求返回数据后,通过异步操作更新RecyclerView的数据,但界面始终没有刷新。网络请求采用异步方式,数据更新在回调函数中执行。

代码片段:RecyclerView 初始化及数据更新

RecyclerView 初始化:

UserRecyclerViewAdapter adapter = new UserRecyclerViewAdapter(this.fragment.getActivity()); this.binding.users.setAdapter(adapter); this.binding.users.setLayoutManager(new LinearLayoutManager(this.fragment.getContext()));

数据更新:

public void getData(boolean append) {     // ... 省略部分代码 ...     UserApi api = new UserApi(activity);     api.index(dto)             .thenAccept((response) -> {                 List<IndexUserApiResponseDto.User> data = response.getContent();                 UserRecyclerViewAdapter adapter = (UserRecyclerViewAdapter) this.binding.users.getAdapter();                 List<UserRecyclerViewAdapter.Item> items = new ArrayList<>();                 data.stream().forEach(user -> {                     IndexUserApiResponseDto.User.UserArchive userArchive = user.getUserArchive();                     if (userArchive != null) {                         UserRecyclerViewAdapter.Item item = new UserRecyclerViewAdapter.Item();                         item.setCover(userArchive.getCover());                         // ...  此处需补充完整的数据赋值 ...                         items.add(item); // 添加到items列表中                     }                 });                 // ... 省略部分代码 ...                 activity.runOnuiThread(() -> { // 在线程更新UI                     if (append) {                         adapter.addAll(items);                     } else {                         adapter.resetAll(items);                     }                 });             })             .exceptionally(LogUtils::throwException)             .thenRun(() -> {                 // ... 省略部分代码 ...             }); }

适配器代码:

public class UserRecyclerViewAdapter extends RecyclerView.Adapter<UserViewHolder> {     // ... 省略部分代码 ...     public void addAll(List<Item> items) {         this.items.addAll(items);         notifyDataSetChanged(); // 确保在主线程调用     }      public void resetAll(List<Item> items) {         this.items.clear();         this.items.addAll(items);         notifyDataSetChanged(); // 确保在主线程调用     }     // ... 省略部分代码 ... }

问题分析及解决方案:

  1. notifyDataSetChanged() 的调用时机: 尽管addAll() 和 resetAll() 方法内部调用了 notifyDataSetChanged(),但它们在异步回调中执行。如果items 列表为空或Item 对象数据不完整,notifyDataSetChanged() 无法正确更新UI。

  2. 数据完整性: 代码中仅设置了 item.setCover(…),Item 对象的其他字段未赋值。必须确保 Item 对象所有字段都正确赋值,RecyclerView才能正确显示数据。 并且,需要将创建好的item添加到items列表中。

  3. UI 线程更新: 由于网络请求是异步操作,数据更新必须在主线程执行。 使用 runOnUiThread() 方法确保在主线程更新 UI。 代码已修正为在主线程中调用adapter.addAll() 和 adapter.resetAll()。

通过以上改进,可以确保RecyclerView在数据更新后正确刷新视图。 请务必检查 items 列表是否为空,以及 Item 对象是否包含完整数据。 同时,必须在主线程中调用 notifyDataSetChanged() 方法。

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享