【问题标题】:RecyclerView.Adapter ClassCastException when scrolling a lot滚动很多时 RecyclerView.Adapter ClassCastException
【发布时间】:2020-01-20 10:01:47
【问题描述】:

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

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

经过长时间的聊天和不同的viewholders生成和膨胀,如果我快速滚动,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)

【问题讨论】:

  • 最终 ViewHolder2 持有者 = (QuickRepliesViewHolder) 持有者;这条线本身告诉错误。您不能将不同的类强制转换变量传递给任何其他类。
  • 对不起,这是一个错字。现已编辑
  • 需要回答更多代码,同时发布 logcat。也有可能您的案例不匹配,并且在 onCreateViewHolder 时返回 null
  • @AnkushBist 添加了错误。不,我不想匹配 null;
  • @AnkushBist,我不明白为什么这个错误只在我快速滚动而不是在聊天时发生

标签: android android-recyclerview adapter classcastexception


【解决方案1】:

对于面临类似情况的任何人,我的主 RecyclerViews 和子 RecyclerViews 都有一个共享的 viewPool。

回收视图池允许多个 RecyclerView 共享一个公共 scrape 视图池。如果您有多个带有使用相同视图类型的适配器的 RecyclerView,这可能会很有用,例如,如果您有多个数据集具有由 ViewPager 显示的相同类型的项目视图。

我的通货膨胀中没有相同的 ViewType,所以我发现它必须离开。

删除它时,错误不再存在。此外,我在不同的 xml 文件中修复了我的“命名”,这些文件根据将被调用的 ViewHolder 进行了膨胀。我对一些常见的 TextView 等使用了相同的名称。

【讨论】:

    猜你喜欢
    • 2016-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    相关资源
    最近更新 更多