微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ConcatAdapter导致getItemViewType返回错误的值?

如何解决ConcatAdapter导致getItemViewType返回错误的值?

我有一个RecyclerView适配器,可以处理我多年来使用的几种视图类型。最近,我发现了有关ConcatAdapter的信息,但似乎遇到了一个问题,该问题似乎是为getItemViewType()返回了错误的值。

我有一个用例,我想显示标题,并在标题下方显示项目列表。我已经为标头创建了一个新的适配器类,但是列表项将继续使用我的旧适配器(它还会处理其他几种视图类型)。

所以我串联了两个适配器:

HeaderAdapter headerAdapter = new HeaderAdapter(context);
PostAdapter postAdapter = new PostAdapter(context,postData);

ConcatAdapter concatAdapter = new ConcatAdapter(headerAdapter,postAdapter);
recyclerView.setAdapter(concatAdapter);

这很好,但是当我打开活动时,它立即崩溃并给出错误

java.lang.classCastException:com.myapp.android.adapter.PostAdapter $ PostViewHolder无法转换为com.myapp.android.adapter.PostAdapter $ FooterViewHolder

这毫无意义,因为我什至从未在回收者视图中添加页脚。

我在getItemViewType()中的PostAdapter方法看起来像这样:

@Override
public int getItemViewType(int position) {
    if (data.get(position) instanceof Footer) {
        return TYPE_FOOTER;
    } else if (data.get(position) instanceof Post) {
        return TYPE_POST;
    }

    return -1;
}

我的onBindViewHolder()看起来像这样:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder,int position) {
    switch (holder.getItemViewType()) {
        case TYPE_FOOTER:
            FooterViewHolder vh1 = (FooterViewHolder) holder;
            configureFooterViewHolder(vh1,position);
            break;
        case TYPE_POST:
            PostViewHolder vh2 = (PostViewHolder) holder;
            configurePostViewHolder(vh2,position);
            break;
        default:
            break;
    }
}

但是出于任何原因,即使我从未将页脚作为FooterViewHolder vh1 = (FooterViewHolder) holder;数据的一部分,运行调试器时,调试器仍位于行PostAdapter上。

那为什么要落在这个上面呢?为什么在处理多种视图类型的适配器中,ConcatAdapter会导致这种奇怪的行为?

解决方法

绑定视图持有人时,应使用RecyclerView.Adapters.getItemViewType(position),而不要使用RecyclerView.ViewHolder.getItemViewType()

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder,int position) {
    switch (getItemViewType(position)) { // not holder.getItemViewType()
        case TYPE_FOOTER:
            FooterViewHolder vh1 = (FooterViewHolder) holder;
            configureFooterViewHolder(vh1,position);
            break;
        case TYPE_POST:
            PostViewHolder vh2 = (PostViewHolder) holder;
            configurePostViewHolder(vh2,position);
            break;
        default:
            break;
    }
}

出现错误是因为视图持有者被回收,它可以是任何视图持有者,因此当您将其强制转换为错误的类时,它抛出了ClassCastException

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。