notifyDataSetChanged () не может корректно обновиться из-за проблем привязки ArrayList к адаптеру - PullRequest
0 голосов
/ 19 января 2019

Я прочитал следующее:

ArrayList не обновляется после использования .clear ()
notifydataSetChanged работает, но показывает только 1 результат в списке просмотра Android
notifyDataSetChanged () не влияет на мой адаптер. View
Android: notifyDataSetChanged (); не работает
notifydatasetchanged () не работает после onbackpressed ()
Android notifyDataSetChanged не работает
Android notifyDataSetChanged () не работает

И все еще не удается обновить адаптер из нового набора данных.

Мой код в режиме отладки выглядит следующим образом:

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 = (Назначение @ 5496) "Назначение {mType = 'Ветеринар', mProviderName = 'красный Ветеринар '} "

mAdapter = new AssignmentsAdapter(this, listAssignments);   

На этапе отладки:
mAdapter = (AssignmentsAdapter @ 5499)
listAssignments = (ArrayList @ 5461) size = 1
0 = (Назначение @ 5496) "Назначение {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) size = 0 **

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

В данный момент в режиме отладки:
mAdapter = (AssignmentsAdapter @ 5499)
listAssignments = (ArrayList @ 5594) size = 1
0 = (Назначение @ 5607) "Назначение {mType = 'Ветеринар', mProviderName = 'red vet'}"

mAdapter.notifyDataSetChanged();
}  

В этот момент на экране ничего не отображается, когда должен отображаться текст, показанный в Назначении @ 5607. Похоже, что notififyDataSetChanged () уведомил mAdapter об изменении текста, показанного в onCreate (ArrayList @ 5461), для очистки в onResume (ArrayList @ 5461), но не для нового вызова данных в onResume (ArrayList @ 5594).

Кажется, это указывает на то, что когда mAdapter был инициализирован для listAssignments, он был установлен для использования ArrayList по адресу @ 5461. Когда в onResume был сделан вызов для новых данных, в а) возврат из использования кнопки «Назад» и (б) при первом запуске этого действия новый ArrayList был создан по другому адресу.

Поэтому, похоже, что я не включил свой ArrayList должным образом, так как все обновления listAssignments приведут к созданию совершенно нового объекта ArrayList, который никогда не используется для обновления mAdapter, который всегда будет обновляться до исходного ArrayList по адресу @ 5461.

Я искал информацию о том, как правильно связать Адаптер с ArrayList, но я не нашел ничего, на что ссылается больше, чем я. Я предполагаю, что целью notifyDataSetChanged () является обновление с использованием существующего Адаптера, чтобы не было необходимости уничтожать существующий Адаптер, а новый, созданный при каждом изменении набора данных, выводится здесь:

notifyDataSetChanged () не может обновить адаптер при нажатии

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Хорошо, я выхожу на конечность и говорю, что notifyDataSetChanged () не работает для ArrayList, потому что при каждой загрузке его адрес меняется, см. Мой оригинальный пост и комментарии к pnavk, чтобы увидеть детали.Насколько я понимаю, Java не предоставляет средств для установки в камне адреса ArrayList, как это делает C или C ++ через указатель, поэтому Adapter устанавливается в ячейку памяти исходного объекта ArrayList и поэтому указывает на одни и те же данные на каждомВызов notifyDataSetChanged (), даже несмотря на то, что Java использовала новую ячейку памяти для этого объекта ArrayList или создала новый объект ArrayList с тем же именем.

Поэтому мой ответ для обновления RecyclerView из нового набора данных вArrayList должен сбросить адаптер в onResume как новый, а затем переназначить этот адаптер в свой RecyclerView, как я упоминал в своем ответе на pnavk:

mAdapter = new AssignmentsAdapter(this, listAssignments); 
mRecyclerView.setAdapter(mAdapter);
0 голосов
/ 19 января 2019

Ссылка, которую вы передаете в 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();
}
...