Замените notifyDataSetChanged на DiffUtil с привязкой данных, LiveData в MVVM - PullRequest
0 голосов
/ 10 октября 2019

Пример Google для приложения TODO с использованием MVVM, привязки данных, LiveData и notifyDataSetChanged (). Я хотел бы заменить это на DiffUtil. Образец перезагружает данные в функции onResume фрагментов.

TasksFragment.java

Перезагружает весь набор данных в функции onResume.

@Override
public void onResume() {
    super.onResume();
    mTasksViewModel.start();
}

tasks_frag.xml

<ListView
    android:id="@+id/tasks_list"
    app:items="@{viewmodel.items}"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Адаптер

public class TasksAdapter extends BaseAdapter {
    private final TasksViewModel mTasksViewModel;
    private List<Task> mTasks;

    private void setList(List<Task> tasks) {
        mTasks = tasks;
        notifyDataSetChanged();
    }
}

TasksListBindings.java

public class TasksListBindings {

    @SuppressWarnings("unchecked")
    @BindingAdapter("app:items")
    public static void setItems(ListView listView, List<Task> items) {
        TasksAdapter adapter = (TasksAdapter) listView.getAdapter();
        if (adapter != null)
        {
            adapter.setData(items);
        }
    }
}

Я уже реализовал DiffUtil как замену notifyDataSetChanged следующим образом.

protected void setList(List<Item> tasks) {
    Log.d("customeee", "mTasks setList");
    final ItemsDiffCallback diffCallback = new ItemsDiffCallback(this.mTasks, tasks);
    final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);

    diffResult.dispatchUpdatesTo(this);
    this.mTasks.clear();
    this.mTasks.addAll(tasks);

}

Но что бы ни случилось, независимо от того, что я делаю, функция areContentsTheSame всегда возвращает true. Если я установлю false, обновление будет работать нормально.

@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
    final Item oldItem = mOldList.get(oldItemPosition);
    final Item newItem = mNewList.get(newItemPosition);

    Log.d("customeee", oldItem.getNote() + " newItem: "+newItem.getNote());
    Log.d("customeee", "New == old? "+mOldList.equals(mNewList));

    return oldItem.getNote().equals(newItem.getNote());
}

oldItem.getNote () и newItem.getNote () возвращают новое значение. Я думаю, что это что-то делать со ссылкой, если объект списка, как oldList.equals (newList).

1 Ответ

0 голосов
/ 15 октября 2019

Решение:

Вместо непосредственного использования DiffUtil компания Google предложила новое решение - AsyncListDiffer. Этот небольшой пример кода из ссылки на класс принес ответ.

Также я что-то упустил. В примере Google они создают новый объект для сохранения в хранилище. Что необходимо:

item = new Item(title.getValue(), description.getValue(), mTaskId, mItemCompleted);
updateItem(item);

Я просто обновил существующий объект новыми ожидаемыми значениями:

this.item.getValue().setFavorite(favorite.getValue());
this.item.getValue().setNote(note.getValue());
updateTask(item.getValue());

Следуя руководству по реализации AsyncListDiffer и пример приложения Google помогли мне решить эту проблему.

...