Элементы ListAdapter отображаются неправильно при вызове метода onDhanged () LiveData. Возможная проблема с DiffUtil areContentsTheSame ()? - PullRequest
1 голос
/ 20 января 2020

В настоящее время я создаю приложение Android, которое поможет вам выполнять задачи. Я использую LiveData вместе с ListAdapter, который перечисляет все различные задачи в Fragment и DiffUtil для проверки на изменения в ListAdapter. Прежде чем объяснить мою проблему: вот некоторый соответствующий код:

SubTaskFragment. java:

public class SubTaskFragment extends Fragment {
private RecyclerView recyclerView;

private SubTaskAdapter adapter;
private SubTaskViewModel viewModel;

private static final String TAG = "SubTaskFragment";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment and setup recycler view
    View rootView = inflater.inflate(R.layout.fragment_sub_task, container, false);
    recyclerView = (RecyclerView) rootView.findViewById(R.id.sub_task_recycler_view);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    //set adapter
    adapter = new SubTaskAdapter(getContext());
    recyclerView.setAdapter(adapter);

    viewModel = ViewModelProviders.of(this).get(SubTaskViewModel.class);
    viewModel.getSubTasks().observe(getViewLifecycleOwner(), new Observer<List<SubTask>>() {
        @Override
        public void onChanged(@Nullable List<SubTask> subTasks) {
            //Update RecyclerView
            Log.d(TAG, "onChanged: subTasks length = " + subTasks.size());
            adapter.submitList(subTasks);
        }
    });

SubTaskAdapter. java

public class SubTaskAdapter extends ListAdapter<SubTask, SubTaskAdapter.ViewHolder> {
private static final String TAG = "SubTaskAdapter";

private SubTaskViewModel subTaskViewModel;

public SubTaskAdapter(Context context) {
    super(DIFF_CALLBACK);
    this.context = context;
}

private static final DiffUtil.ItemCallback<SubTask> DIFF_CALLBACK = new DiffUtil.ItemCallback<SubTask>() {
    @Override
    public boolean areItemsTheSame(@NonNull SubTask oldTask, @NonNull SubTask newTask) {
        Log.d(TAG, "areItemsTheSame: oldTask name: " + oldTask.getName() + " id: " + oldTask.getId() + " ### newTask name: " + newTask.getName() + " id: " + newTask.getId());
        return oldTask.getId() == newTask.getId();
    }

    @Override
    public boolean areContentsTheSame(@NonNull SubTask oldTask, @NonNull SubTask newTask) {
        Log.d(TAG, "areContentsTheSame: oldTask name: " + oldTask.getName() + " ### newTask name: " + newTask.getName());
        boolean contentsSame = oldTask.getName().equals(newTask.getName()) &&
                oldTask.getDueDate().equals(newTask.getDueDate()) &&
                oldTask.isCompleted() == newTask.isCompleted() &&
                oldTask.getMainTaskId() == (newTask.getMainTaskId());
        Log.d(TAG, "areContentsTheSame: = " + contentsSame);
        return contentsSame;
    }
};

@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
    SubTask subTask = getItem(i);
    Log.d(TAG, "onBindViewHolder: pos: " + i + " name: " + subTask.getName() + " Is overdue: " + subTask.isOverdue());

    Log.d(TAG, "onBindViewHolder: " + subTask.getName() + " isOverdue = " + subTask.isOverdue());
    //SET BACKGROUND COLOR OF LIST ITEM
    if (subTask.isOverdue()) {
        viewHolder.card.setCardBackgroundColor(context.getResources().getColor(R.color.red));
        viewHolder.subTaskName.setTextColor(context.getResources().getColor(R.color.colorAccent));
        viewHolder.mainTaskName.setTextColor(context.getResources().getColor(R.color.colorAccent));
    }

    if (subTask.isCompleted()) {
        viewHolder.checkBox.setChecked(true);
        Log.d(TAG, "onBindViewHolder: " + subTask.getName() + " set to checked");
    } else {
        viewHolder.checkBox.setChecked(false);
        Log.d(TAG, "onBindViewHolder: " + subTask.getName() + " set to unchecked");
    }

    viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() 
    {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            Log.d(TAG, "onCheckedChanged: called for subTask " + subTask.getName() + " isChecked = " + isChecked);
            subTaskViewModel = ViewModelProviders.of((FragmentActivity) context).get(SubTaskViewModel.class);
            if (isChecked) {
                subTask.setCompleted(true);
                subTaskViewModel.updateSubTask(subTask);
            } else {
                subTask.setCompleted(false);
                subTaskViewModel.updateSubTask(subTask);
            }
        }
    });

Первая проблема Я сталкиваюсь с тем, что, поскольку флажок элемента списка установлен пользователем, элемент списка становится серым , как, например, . Это не ожидаемое поведение, так как цвет элемента списка не должен изменяться при его проверке. Этого не происходит, если его не проверять.

Вот протокол этого действия:

2020-01-19 15:24:47.572 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onCheckedChanged: called for subTask Test 1 isChecked = true
2020-01-19 15:24:47.575 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskViewModel: updateSubTask: CALLED for Test 1 isCompleted = true isOverdue = false
2020-01-19 15:24:47.602 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskFragment: onChanged: subTasks length = 5
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Wash car id: 3 ### newTask name: Wash car id: 3
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read OS book id: 2 ### newTask name: Read OS book id: 2
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read database book id: 1 ### newTask name: Read database book id: 1
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 1 id: 4 ### newTask name: Test 1 id: 4
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 2 id: 5 ### newTask name: Test 2 id: 5
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 2 id: 5 ### newTask name: Test 2 id: 5
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 1 id: 4 ### newTask name: Test 1 id: 4
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read database book id: 1 ### newTask name: Read database book id: 1
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read OS book id: 2 ### newTask name: Read OS book id: 2
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Wash car id: 3 ### newTask name: Wash car id: 3
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Wash car ### newTask name: Wash car
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Read OS book ### newTask name: Read OS book
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Read database book ### newTask name: Read database book
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Test 1 ### newTask name: Test 1
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = false
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Test 2 ### newTask name: Test 2
2020-01-19 15:24:47.603 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:24:47.652 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onBindViewHolder: pos: 3 name: Test 1 Is overdue: false
2020-01-19 15:24:47.652 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onBindViewHolder: Test 1 isOverdue = false
2020-01-19 15:24:47.655 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onBindViewHolder: Test 1 set to checked
2020-01-19 15:24:50.633 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onCheckedChanged: called for subTask Test 1 isChecked = false
2020-01-19 15:24:50.633 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskViewModel: updateSubTask: CALLED for Test 1 isCompleted = false isOverdue = false
2020-01-19 15:24:50.664 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskFragment: onChanged: subTasks length = 5
2020-01-19 15:24:50.664 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Wash car id: 3 ### newTask name: Wash car id: 3
2020-01-19 15:24:50.664 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read OS book id: 2 ### newTask name: Read OS book id: 2
2020-01-19 15:24:50.664 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read database book id: 1 ### newTask name: Read database book id: 1
2020-01-19 15:24:50.664 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 1 id: 4 ### newTask name: Test 1 id: 4
2020-01-19 15:24:50.664 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 2 id: 5 ### newTask name: Test 2 id: 5
2020-01-19 15:24:50.664 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 2 id: 5 ### newTask name: Test 2 id: 5
2020-01-19 15:24:50.664 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 1 id: 4 ### newTask name: Test 1 id: 4
2020-01-19 15:24:50.664 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read database book id: 1 ### newTask name: Read database book id: 1
2020-01-19 15:24:50.664 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read OS book id: 2 ### newTask name: Read OS book id: 2
2020-01-19 15:24:50.664 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Wash car id: 3 ### newTask name: Wash car id: 3
2020-01-19 15:24:50.664 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Wash car ### newTask name: Wash car
2020-01-19 15:24:50.665 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:24:50.665 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Read OS book ### newTask name: Read OS book
2020-01-19 15:24:50.665 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:24:50.665 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Read database book ### newTask name: Read database book
2020-01-19 15:24:50.665 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:24:50.665 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Test 1 ### newTask name: Test 1
2020-01-19 15:24:50.665 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:24:50.665 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Test 2 ### newTask name: Test 2
2020-01-19 15:24:50.665 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true

Следующая, и, возможно, связанная, проблема, с которой я сталкиваюсь, - это когда элемент списка "" просрочено "(задачи красного цвета) , и я отмечаю его , другие элементы в ListAdapter становятся красными, когда я нажимаю соответствующий флажок . Это не способ, которым это должно функционировать. Эти элементы списка должны быть белыми, поскольку эти задачи не просрочены. В конце концов он снова становится белым, когда я проверяю / снимаю флажок во второй раз.

Приложение работает правильно, когда проверяется просроченная задача. Он удаляется с экрана, поскольку проверенная просроченная задача больше не возвращается моим оператором SQL SELECT.

Вот журнал, когда я дважды проверяю / снимаю отметку с не просроченного элемента списка (3-й GIF). Здесь важно отметить, что при проверке теста 1 areContentsTheSame() правильно возвращает false, когда проверяется элемент списка, поскольку для isCompleted установлено значение true в false. Тем не менее, areContentsTheSame() неверно возвращает true, когда не отмечено, хотя isCompleted был установлен с true на false. Кроме того, хотя isOverdue имеет значение false, элемент списка внезапно становится красным:

2020-01-19 15:28:52.071 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onCheckedChanged: called for subTask Test 1 isChecked = true
2020-01-19 15:28:52.072 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskViewModel: updateSubTask: CALLED for Test 1 isCompleted = true isOverdue = false
2020-01-19 15:28:52.104 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskFragment: onChanged: subTasks length = 4
2020-01-19 15:28:52.104 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Wash car id: 3 ### newTask name: Wash car id: 3
2020-01-19 15:28:52.104 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read OS book id: 2 ### newTask name: Read OS book id: 2
2020-01-19 15:28:52.104 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 1 id: 4 ### newTask name: Test 1 id: 4
2020-01-19 15:28:52.104 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 2 id: 5 ### newTask name: Test 2 id: 5
2020-01-19 15:28:52.104 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 2 id: 5 ### newTask name: Test 2 id: 5
2020-01-19 15:28:52.104 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 1 id: 4 ### newTask name: Test 1 id: 4
2020-01-19 15:28:52.105 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read OS book id: 2 ### newTask name: Read OS book id: 2
2020-01-19 15:28:52.105 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Wash car id: 3 ### newTask name: Wash car id: 3
2020-01-19 15:28:52.105 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Wash car ### newTask name: Wash car
2020-01-19 15:28:52.105 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:52.105 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Read OS book ### newTask name: Read OS book
2020-01-19 15:28:52.105 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:52.105 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Test 1 ### newTask name: Test 1
2020-01-19 15:28:52.105 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = false
2020-01-19 15:28:52.105 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Test 2 ### newTask name: Test 2
2020-01-19 15:28:52.105 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:52.136 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onBindViewHolder: pos: 2 name: Test 1 Is overdue: false
2020-01-19 15:28:52.137 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onBindViewHolder: Test 1 isOverdue = false
2020-01-19 15:28:52.137 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onBindViewHolder: Test 1 set to checked
2020-01-19 15:28:54.080 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onCheckedChanged: called for subTask Test 1 isChecked = false
2020-01-19 15:28:54.081 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskViewModel: updateSubTask: CALLED for Test 1 isCompleted = false isOverdue = false
2020-01-19 15:28:54.102 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskFragment: onChanged: subTasks length = 4
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Wash car id: 3 ### newTask name: Wash car id: 3
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read OS book id: 2 ### newTask name: Read OS book id: 2
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 1 id: 4 ### newTask name: Test 1 id: 4
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 2 id: 5 ### newTask name: Test 2 id: 5
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 2 id: 5 ### newTask name: Test 2 id: 5
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 1 id: 4 ### newTask name: Test 1 id: 4
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read OS book id: 2 ### newTask name: Read OS book id: 2
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Wash car id: 3 ### newTask name: Wash car id: 3
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Wash car ### newTask name: Wash car
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Read OS book ### newTask name: Read OS book
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Test 1 ### newTask name: Test 1
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Test 2 ### newTask name: Test 2
2020-01-19 15:28:54.103 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:58.480 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onCheckedChanged: called for subTask Test 1 isChecked = true
2020-01-19 15:28:58.481 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskViewModel: updateSubTask: CALLED for Test 1 isCompleted = true isOverdue = false
2020-01-19 15:28:58.498 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskFragment: onChanged: subTasks length = 4
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Wash car id: 3 ### newTask name: Wash car id: 3
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read OS book id: 2 ### newTask name: Read OS book id: 2
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 1 id: 4 ### newTask name: Test 1 id: 4
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 2 id: 5 ### newTask name: Test 2 id: 5
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 2 id: 5 ### newTask name: Test 2 id: 5
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 1 id: 4 ### newTask name: Test 1 id: 4
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read OS book id: 2 ### newTask name: Read OS book id: 2
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Wash car id: 3 ### newTask name: Wash car id: 3
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Wash car ### newTask name: Wash car
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Read OS book ### newTask name: Read OS book
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Test 1 ### newTask name: Test 1
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = false
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Test 2 ### newTask name: Test 2
2020-01-19 15:28:58.499 27375-27504/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:58.529 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onBindViewHolder: pos: 2 name: Test 1 Is overdue: false
2020-01-19 15:28:58.529 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onBindViewHolder: Test 1 isOverdue = false
2020-01-19 15:28:58.529 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onBindViewHolder: Test 1 set to checked
2020-01-19 15:28:59.922 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskAdapter: onCheckedChanged: called for subTask Test 1 isChecked = false
2020-01-19 15:28:59.922 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskViewModel: updateSubTask: CALLED for Test 1 isCompleted = false isOverdue = false
2020-01-19 15:28:59.941 27375-27375/com.johnsorhannus.divideandconquer D/SubTaskFragment: onChanged: subTasks length = 4
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Wash car id: 3 ### newTask name: Wash car id: 3
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read OS book id: 2 ### newTask name: Read OS book id: 2
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 1 id: 4 ### newTask name: Test 1 id: 4
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 2 id: 5 ### newTask name: Test 2 id: 5
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 2 id: 5 ### newTask name: Test 2 id: 5
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Test 1 id: 4 ### newTask name: Test 1 id: 4
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Read OS book id: 2 ### newTask name: Read OS book id: 2
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areItemsTheSame: oldTask name: Wash car id: 3 ### newTask name: Wash car id: 3
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Wash car ### newTask name: Wash car
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Read OS book ### newTask name: Read OS book
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Test 1 ### newTask name: Test 1
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: oldTask name: Test 2 ### newTask name: Test 2
2020-01-19 15:28:59.941 27375-27409/com.johnsorhannus.divideandconquer D/SubTaskAdapter: areContentsTheSame: = true

Еще одна вещь, которую я замечаю, состоит в том, что areItemsTheSame() вызывается дважды для каждого элемента в списке, в то время как areContentsTheSame() вызывается только один раз для каждого элемента списка. Это не кажется нормальным поведением, поэтому это может как-то способствовать проблеме. Есть мысли о том, связаны ли эти две проблемы и как их исправить?

1 Ответ

1 голос
/ 20 января 2020

У вас есть два вопроса здесь. Первая (серая подсветка) происходит из-за встроенной анимации по умолчанию RecyclerView. Когда вы устанавливаете флажок, RecyclerView создает новый ViewHolder и выполняет кроссфейд. См. Этот вопрос / ответ для получения дополнительной информации о том, как решить эту проблему: RecyclerView.ItemDecoration не обновляется после удаления элемента из RecyclerView.Adapter

Второй (красный фон) является ошибка в вашем onBindViewHolder() методе, который препятствует правильной переработке представлений:

if (subTask.isOverdue()) {
    viewHolder.card.setCardBackgroundColor(context.getResources().getColor(R.color.red));
    viewHolder.subTaskName.setTextColor(context.getResources().getColor(R.color.colorAccent));
    viewHolder.mainTaskName.setTextColor(context.getResources().getColor(R.color.colorAccent));
}

Каждое подобное утверждение if нуждается в случае else, чтобы установить представления обратно в нормальные цвета. Без такого else ваш красный вид возвращается в другое положение, и ничто не меняет цвет назад .

...