ListAdapter项目在调用LiveData onChanged()方法时显示不正确。 DiffUtil areContentsTheSame()可能存在的问题?

问题描述 投票:0回答:1

我当前正在创建一个可帮助您完成任务的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);
            }
        }
    });

我遇到的第一个问题是,当用户选中列表项的复选框时,列表项会变成灰色like so。这不是预期的行为,因为列表项的颜色在检查时不应更改。如果未选中,则不会发生这种情况。

这是此操作的日志:

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

我遇到的下一个问题,可能是相关的问题是,列表项“过期”(红色任务)and I check it off,列表适配器“ C0”中的其他项。这不是它应该起作用的方式。这些列表项应该是白色的,因为这些任务尚未过期。当我第二次选中/取消选中它时,它最终再次变回白色。

检查了过期任务后,该应用程序将正常运行。它从屏幕上删除,因为我的SQL SELECT语句不再返回已检查的过期任务。

这里是我两次检查/取消检查未逾期的清单项目时的日志(第3个gif)。这里要注意的重要一件事是,当选中测试1时,由于将isCompleted从true设置为false,因此检查列表项时turn red when I hit it's corresponding checkbox正确返回false。但是,即使isCompleted已从true设置为false,当未选中areContentsTheSame()时,它也会错误地返回true。同样,即使isOverdue为false,列表项也突然变成红色:

areContentsTheSame()

[我要注意的另一件事是,列表中的每个项目都两次调用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()。这似乎不是正常的行为,所以这可能以某种方式导致了问题。关于这两个问题是否相关以及如何解决它们有任何想法吗?

java android listadapter android-diffutils
1个回答
0
投票

您在这里遇到了两个问题。由于RecyclerView内置了默认动画,因此发生了第一个(灰色高光)。选中该框时,RecyclerView将创建一个新的areContentsTheSame()并进行交叉淡入淡出。有关如何解决此问题的更多信息,请参见此问题/答案:ViewHolder

第二个(红色背景)是您的RecyclerView.ItemDecoration doesn't update after item is removed from 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,您的红色视图将被回收到另一个位置,并且颜色back不变。

© www.soinside.com 2019 - 2024. All rights reserved.