使用DiffUtil更新异构RecyclerView - Android

时间:2018-03-23 07:49:12

标签: android android-recyclerview refresh updates

更新的问题:

我有一个带有异类项目的RecyclerView(RecyclerView包含两种视图类型的项目)。我想使用从API收到的新数据更新此RecyclerView。

所有示例和实现都显示DiffUtil,用于更新包含单个视图类型的项目的RecyclerView。

我是Android的初学者并尝试了以下代码 -

public class TestDiffCallback extends DiffUtil.Callback {
    private final List<Object> oldList;
    private final List<Object> newList;

    public TestDiffCallback(List<Object> oldList, List<Object> newList) {
        this.oldList = oldList;
        this.newList= newList;
    }

    @Override
    public int getOldListSize() {
        return oldList.size();
    }

    @Override
    public int getNewListSize() {
        return newList.size();
    }

    @Override
    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
        if (oldList.get(oldItemPosition) instanceof ViewType1) {
            return (((ViewType1) oldList.get(oldItemPosition)).getUniqueID())
                    .equals(((ViewType1) newList.get(newItemPosition)).getUniqueID());
        } else if (oldList.get(oldItemPosition) instanceof ViewType2) {
            return (((ViewType2) oldList.get(oldItemPosition)).getUniqueID())
                    .equals(((ViewType2) newList.get(newItemPosition)).getUniqueID());
        }
        return false;
    }

    @Override
    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
        if (oldList.get(oldItemPosition) instanceof ViewType1) {
            final ViewType1 oldViewType1 = (ViewType1) oldList.get(oldItemPosition);
            final ViewType1 newViewType1 = (ViewType1) oldList.get(newItemPosition);

            return (
                    oldViewType1.getUniqueID().equals(newViewType1.getUniqueID())
            );
        } else if (oldList.get(oldItemPosition) instanceof ViewType2) {
            final ViewType2 oldViewType2 = (ViewType2) oldList.get(oldItemPosition);
            final ViewType2 newViewType2 = (ViewType2) oldList.get(newItemPosition);

            return (
                    oldViewType2.getUniqueID().equals(newViewType2.getUniqueID())
            );

        }
        return false;
    }

    @Nullable
    @Override
    public Object getChangePayload(int oldItemPosition, int newItemPosition) {
        return super.getChangePayload(oldItemPosition, newItemPosition);
    }
}

在我的异构视图适配器中,我有这个 -

public void updateHomeItems(List<Object> testItems) {
    final TestDiffCallback diffCallback =
            new TestDiffCallback(this.testItems, testItems);
    final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);

    this.testItems.clear();
    this.testItems.addAll(testItems);
    diffResult.dispatchUpdatesTo(this);
}

从我的Fragment类中我从API获取数据并将其传递给DiffUtil,如下所示 -

programAdapter.updateHomeItems(refreshedTestItemsList);

这是我一直得到的错误 -

E/AndroidRuntime: FATAL EXCEPTION: main
                     Process: com.acadnion, PID: 28315
                     io.reactivex.exceptions.UndeliverableException: java.lang.ClassCastException: com.acadnion.models.ViewType2 cannot be cast to com.acadnion.models.ViewType1
                     at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:366)
                     at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:111)
                     at android.os.Handler.handleCallback(Handler.java:751)
                     at android.os.Handler.dispatchMessage(Handler.java:95)
                     at android.os.Looper.loop(Looper.java:154)
                     at android.app.ActivityThread.main(ActivityThread.java:6186)
                     at java.lang.reflect.Method.invoke(Native Method)
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
                     Caused by: java.lang.ClassCastException: com.acadnion.models.ViewType2 cannot be cast to com.acadnion.models.ViewType1
                     at com.acadnion.utils.TestDiffCallback.areItemsTheSame(TestDiffCallback.java:36)
                     at android.support.v7.util.DiffUtil.diffPartial(DiffUtil.java:224)
                     at android.support.v7.util.DiffUtil.calculateDiff(DiffUtil.java:136)
                     at android.support.v7.util.DiffUtil.calculateDiff(DiffUtil.java:97)
                     at com.acadnion.adapters.ProgramAdapter.updateHomeItems(ProgramAdapter.java:160)
                     at com.acadnion.fragments.TestFragment.addFetchedDataToList(TestFragment.java:182)
                     at com.acadnion.fragments.TestFragment.access$100(TestFragment.java:45)
                     at com.acadnion.fragments.TestFragment$3.onNext(TestFragment.java:153)
                     at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:200)
                     at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252)
                     at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109)
                     at android.os.Handler.handleCallback(Handler.java:751) 
                     at android.os.Handler.dispatchMessage(Handler.java:95) 
                     at android.os.Looper.loop(Looper.java:154) 
                     at android.app.ActivityThread.main(ActivityThread.java:6186) 
                     at java.lang.reflect.Method.invoke(Native Method) 
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) 
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779) 

0 个答案:

没有答案