为了账号安全,请及时绑定邮箱和手机立即绑定

由于 ArrayList 到适配器绑定问题,notifyDataSetChanged()

由于 ArrayList 到适配器绑定问题,notifyDataSetChanged()

慕田峪7331174 2022-05-12 17:22:35
并且仍然无法让我的适配器从新数据集中进行更新。我在调试模式下的代码如下:public class PetInformationActivity extends AppCompatActivityimplements ConfirmDialogFragment.ConfirmDialogListener, MedicalInformationFragment.OnFragmentInteractionListener{private static List<Assignment> listAssignments = new ArrayList<>();private static AssignmentsAdapter mAdapter;private static PetInformationViewModel sPetInformationViewModel;...protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);.../*** get the providers' IDs assigned to the pet: fillAssignmentsArray()*/listAssignments = sPetInformationViewModel.getAssignedProviders(petId);此时调试中:mAdapter = nulllistAssignments = (ArrayList@5411) size = 0Log.d(TAG, "listAssignments has " + listAssignments.size() + " Assignment objects in it");  Log.d(TAG, "listAssignments is: " + listAssignments);   此时调试中:mAdapter = nulllistAssignments = (ArrayList@5461) size = 10 = (Assignment@5496)"Assignment{mType='Veterinarian', mProviderName='red vet'}"mAdapter = new AssignmentsAdapter(this, listAssignments);   此时调试中:mAdapter = (AssignmentsAdapter@5499)listAssignments = (ArrayList@5461) size = 10 = (Assignment@5496)"Assignment{mType='Veterinarian', mProviderName='red vet'}"mRecyclerView.setAdapter(mAdapter);...}public void onResume(){super.onResume();Log.d(TAG, "Entered: onResume");listAssignments.clear();Log.d(TAG, "listAssignments is: " + listAssignments);此时屏幕是空白的,它应该显示在 Assignment@5607 中显示的文本。似乎 notififyDataSetChanged() 通知 mAdapter 将 onCreate (ArrayList@5461) 中显示的文本更改为清除 onResume (ArrayList@5461),但没有通知 onResume (ArrayList@5594) 中对数据的新调用。这似乎表明当 mAdapter 初始化为 listAssignments 时,它被设置为使用地址 @5461 的 ArrayList。当在 onResume 中调用新数据时,在 a) 使用后退按钮返回和 (b) 当此 Activity 首次启动时,会在不同的地址创建一个新的 ArrayList。因此,我似乎没有正确地合并我的 ArrayList,因为对 listAssignments 的所有更新都会产生一个全新的 ArrayList 对象,该对象永远不会用于更新 mAdapter,它将始终更新为地址 @5461 处的初始 ArrayList。我已经搜索了有关如何正确地将适配器绑定到 ArrayList 的信息,但我没有找到任何暗示比我所做的更多的信息。我假设 notifyDataSetChanged() 的目的是使用现有的适配器进行更新,这样现有的适配器就不必被销毁,并且在每个数据集更改时创建一个新的适配器
查看完整描述

2 回答

?
四季花海

TA贡献1811条经验 获得超5个赞

好吧,我在这里跑题了,说 notifyDataSetChanged() 不适用于 ArrayList,因为在每次加载时,它的地址都会发生变化,请参阅我的原始帖子和对 pnavk 的评论以查看详细信息。据我了解,Java 无法像 C 或 C++ 那样通过指针固定 ArrayList 的地址,因此适配器被设置为原始 ArrayList 对象的内存位置,因此每次都指向相同的数据即使 Java 为该 ArrayList 对象使用了新的内存位置,或者创建了一个全新的同名 ArrayList 对象,也会调用 notifyDataSetChanged()。

因此,我从 ArrayList 中的新数据集更新 RecyclerView 的答案是将 onResume 中的 Adapter 重置为新的,然后将该 Adapter 重新分配给您的 RecyclerView,正如我在对 pnavk 的回复中提到的那样:

mAdapter = new AssignmentsAdapter(this, listAssignments);
 mRecyclerView.setAdapter(mAdapter);


查看完整回答
反对 回复 2022-05-12
?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

您传递给 ArrayAdapter 的引用与此处分配的引用不同:


listAssignments = sPetInformationViewModel.getAssignedProviders(petId);

就 ArrayAdapter 而言,它所引用的 listAssignments 已被清除 OnResume 并且没有任何内容被添加回它。它对新的 listAssignments 参考一无所知。


尝试这样做:


public void onResume()

{

    super.onResume();

    Log.d(TAG, "Entered: onResume");

    listAssignments.clear();

    Log.d(TAG, "listAssignments is: " + listAssignments);

    List<Assignment> newList = sPetInformationViewModel.getAssignedProviders(petId);

    listAssignments.addAll(newList);

    mAdapter.notifyDataSetChanged();

}


查看完整回答
反对 回复 2022-05-12
  • 2 回答
  • 0 关注
  • 152 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号