Android RecyclerView數(shù)據(jù)更新后視圖不刷新,如何解決?

Android RecyclerView數(shù)據(jù)更新后視圖不刷新,如何解決?

android RecyclerView數(shù)據(jù)更新后視圖不刷新:問題詳解及解決方案

在Android開發(fā)中,RecyclerView是常用的數(shù)據(jù)展示組件。然而,更新數(shù)據(jù)后視圖卻無法刷新,是開發(fā)者常遇到的問題。本文將分析此問題,并提供解決方案。

問題描述:

開發(fā)者使用RecyclerView展示用戶數(shù)據(jù),網(wǎng)絡(luò)請求(異步操作)完成后,數(shù)據(jù)更新但視圖未刷新。數(shù)據(jù)更新在適配器中進(jìn)行,網(wǎng)絡(luò)請求使用異步回調(diào)(非線程)。

代碼示例:

初始化RecyclerView:

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

更新數(shù)據(jù):

public void getData(boolean append) {     // ... 省略部分代碼     userApi api = new userApi(activity);     api.index(dto)             .thenAccept((response) -> {                 List<IndexUserApiResponseDto.User> data = res.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());                         // ...  設(shè)置item的其他屬性                         items.add(item);                     }                 });                 // 更新ui必須在主線程                 activity.runOnUiThread(() -> {                     if (!items.isEmpty()) {                         if (append) {                             adapter.addAll(items);                         } else {                             adapter.resetAll(items);                         }                         adapter.notifyDataSetChanged();                     }                 });             })             .exceptionally(LogUtils::throwException)             .thenRun(() -> {                 // ... 省略部分代碼             }); }

適配器代碼:

public class userRecyclerViewAdapter extends RecyclerView.Adapter<UserViewHolder> {      private final Activity activity;     private final List<Item> items = new ArrayList<>();      // ... 省略部分代碼      public void addAll(List<Item> items) {         this.items.addAll(items);     }      public void resetAll(List<Item> items) {         this.items.clear();         this.items.addAll(items);     }      @Override     public void onBindViewHolder(@NonNull UserViewHolder holder, int position) {         Item item = this.items.get(position);         holder.getTitleView().setText(item.getTitle()); //確保所有屬性都已設(shè)置         // ...     }      @Override     public int getItemCount() {         return this.items.size();     } }

問題分析及解決方案:

  1. 異步操作與UI更新: 網(wǎng)絡(luò)請求在后臺(tái)線程執(zhí)行,數(shù)據(jù)更新也發(fā)生在后臺(tái)線程。直接操作UI會(huì)拋出異常。解決方案:使用runOnUiThread()將數(shù)據(jù)更新和notifyDataSetChanged()放在主線程執(zhí)行。

  2. notifyDataSetChanged()的調(diào)用: 雖然代碼調(diào)用了addAll()和resetAll(),但RecyclerView并不知道數(shù)據(jù)已改變,需要顯式調(diào)用notifyDataSetChanged()通知RecyclerView刷新。

  3. 數(shù)據(jù)完整性: 確保Item對象的屬性都已正確賦值。

  4. 空數(shù)據(jù)處理: 檢查items列表是否為空??樟斜碚{(diào)用notifyDataSetChanged()也不會(huì)刷新視圖。

通過在thenAccept塊中使用runOnUiThread包裹數(shù)據(jù)更新和notifyDataSetChanged(),并確保Item對象數(shù)據(jù)完整以及處理空數(shù)據(jù)情況,即可解決RecyclerView數(shù)據(jù)更新后視圖不刷新的問題。 代碼示例中已體現(xiàn)了這些改進(jìn)。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊14 分享