由于ArrayList到适配器的绑定问题,notifyDataSetChanged()无法正确更新

时间:2019-01-18 23:08:06

标签: java android arraylist notifydatasetchanged

我已阅读以下内容:

ArrayList not updating after using .clear()
notifydataSetChanged working but only showing 1 result in listview Android
notifyDataSetChanged() does not affect my adapterView
Android: notifyDataSetChanged(); not working
notifydatasetchanged() not working after onbackpressed()
Android notifyDataSetChanged not working
Android notifyDataSetChanged() not working

仍然无法让我的适配器从新数据集更新。

我在调试模式中的代码如下:

public class PetInformationActivity extends AppCompatActivity
implements 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 = null
listAssignments =(ArrayList @ 5411)size = 0

Log.d(TAG, "listAssignments has " + listAssignments.size() + " Assignment objects in it");  
Log.d(TAG, "listAssignments is: " + listAssignments);   
  

此时在调试中:
mAdapter = null
listAssignments =(ArrayList @ 5461)size = 1
0 =   (Assignment @ 5496)“工作分配{mType ='兽医',mProviderName ='红色   vet'}“

mAdapter = new AssignmentsAdapter(this, listAssignments);   
  

此时在调试中:
mAdapter =(AssignmentsAdapter @ 5499)
listAssignments =(ArrayList @ 5461)大小   = 1
0 =(Assignment @ 5496)“ Assignment {mType ='兽医',mProviderName ='red vet'}”

mRecyclerView.setAdapter(mAdapter);
.
.
.
}

public void onResume(){
super.onResume();
Log.d(TAG, "Entered: onResume");
listAssignments.clear();
Log.d(TAG, "listAssignments is: " + listAssignments);
  

此时在调试中:
mAdapter =(AssignmentsAdapter @ 5499)
listAssignments =(ArrayList @ 5461)大小   = 0 **

listAssignments = sPetInformationViewModel.getAssignedProviders(petId);
Log.d(TAG, "listAssignments is: " + listAssignments);
  

此时在调试中:
mAdapter =(AssignmentsAdapter @ 5499)
listAssignments =(ArrayList @ 5594)大小   = 1
  0 =(Assignment @ 5607)“ Assignment {mType ='兽医',mProviderName ='red vet'}”

mAdapter.notifyDataSetChanged();
}  

这时屏幕空白,应显示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。

我已经搜索了有关如何将Adapter正确绑定到ArrayList的信息,但是我没有发现任何暗示比我做的更多的事情。我假设notifyDataSetChanged()的意图是使用现有的适配器进行更新,从而不必破坏现有的适配器,并且在每个数据集上创建一个新适配器,如下所示:

notifyDataSetChanged() fails to update adapter onClick

2 个答案:

答案 0 :(得分:0)

您传递给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();
}

答案 1 :(得分:0)

好的,我要走出去,说notifyDataSetChanged()对ArrayList不起作用,因为在每次加载时其地址都会改变,请参阅我的原始帖子和对pnavk的评论以查看详细信息。据我了解,Java没有提供像C或C ++一样通过指针设置ArrayList地址的方法,因此Adapter设置为原始ArrayList对象的内存位置,因此在每个指向相同的数据即使Java为该ArrayList对象使用了新的内存位置,或创建了一个具有相同名称的全新ArrayList对象,都将调用notifyDataSetChanged()调用。

因此,我要根据ArrayList中的新数据集更新RecyclerView的答案是将onResume中的适配器重置为新适配器,然后如我对pnavk的答复中所述将适配器重新分配给您的RecyclerView:

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