Android 大量滚动时的RecyclerView.Adapter ClassCastException

Android 大量滚动时的RecyclerView.Adapter ClassCastException,android,android-recyclerview,adapter,classcastexception,Android,Android Recyclerview,Adapter,Classcastexception,我正在构建一个聊天应用程序,我使用一个带有适配器的RecyclerView,它使用不同的视图持有者,因为服务器发送的内容丰富,需要不同的视图、图表等 当我正常使用该应用程序并与服务器聊天时,询问不同的内容,这意味着不同的用户一切正常。每次我发送不同的请求时,顶级适配器都会将主viewholder转换为所需的主viewholder 经过长时间的聊天,不同的视图持有者生成并膨胀后,如果我快速滚动RecyclerView,向上和向下滚动,主适配器将重新呈现项目,它将因classcastExceptio

我正在构建一个聊天应用程序,我使用一个带有适配器的RecyclerView,它使用不同的视图持有者,因为服务器发送的内容丰富,需要不同的视图、图表等

当我正常使用该应用程序并与服务器聊天时,询问不同的内容,这意味着不同的用户一切正常。每次我发送不同的请求时,顶级适配器都会将主viewholder转换为所需的主viewholder

经过长时间的聊天,不同的视图持有者生成并膨胀后,如果我快速滚动RecyclerView,向上和向下滚动,主适配器将重新呈现项目,它将因classcastException而崩溃,在之前聊天时,它没有崩溃

以下是一个例子:

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {

    LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());

    //depending the type of rich content i get from the server i inflate the respective xml
    switch (MessageType.values()[viewType]) {
        case 1:
            View plainTextView = inflater....
            return new ViewHolder1(plainTextView);
        case 2:
            View secondView = inflater...
            return new ViewHolder2(secondView);
        case 3:
            View thirdView = inflater...
            return new ViewHolder3(verticalView);     
    }
   return null;
}
然后在onBindViewHolder中,我根据onCreateViewHolder的情况强制转换ViewHolder

    @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
                [...]
    case 2:

                    final ViewHolder2 holder = (ViewHolder2) holder;
                    //do stuff
                    break;
错误

2020-01-20 13:22:57.322 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.----.app, PID: 28353
java.lang.ClassCastException: com.-----.ui.adapters.MainCarouselAdapter$CarouselViewHolder cannot be cast to com.----.ui.adapters.QuickRepliesAdapter$OptionsViewHolder
    at com.-----.ui.adapters.QuickRepliesAdapter.onBindViewHolder(QuickRepliesAdapter.java:22)
    at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
    at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
    at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288)
    at androidx.recyclerview.widget.GapWorker.prefetchInnerRecyclerViewWithDeadline(GapWorker.java:335)
    at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:351)
    at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361)
    at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368)
    at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399)
    at android.os.Handler.handleCallback(Handler.java:907)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:216)
    at android.app.ActivityThread.main(ActivityThread.java:7625)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

对于任何面临类似问题的人,我为我的主循环和次循环视图提供了一个共享的视图池

回收的视图池允许多个RecyclerViews共享一个共用的刮取视图池。如果有多个带有适配器的RecyclerViews使用相同的视图类型,例如,如果有多个数据集具有由ViewPager显示的相同类型的项目视图,则此选项非常有用

我没有在我的通货膨胀相同的视图类型,所以我发现它必须离开


当删除它的错误停止存在。此外,我还修复了不同xml文件中的“命名”问题,这些文件的命名取决于将调用的ViewHolder。我对一些常见的文本视图等使用了相同的名称。

final ViewHolder2 holder=(QuickRepliesViewHolder)holder;这一行本身说明了错误。您不能将不同的类强制转换变量传递给任何其他类。很抱歉,这是一个输入错误。现在编辑更多需要回答的代码,也发布日志。您的案例也可能不匹配,并且在执行时返回nullonCreateViewHolder@AnkushBist添加了错误。不,我不想匹配null@AnkushBist,我不明白的是,为什么这个错误只发生在我快速滚动时,而不是聊天时