在多个视图持有者回收视图上引发异常



我在DataListAdapter中使用了多个viewholder。每个支架都有一个适配器。

我的适配器:

public class DataListAdapter extends BaseAdapter<HomeListItem> {
private RecyclerView.RecycledViewPool pool;
public static final int ADS = 10, DATA = 11, PIC = 13, QUE=14;

public DataListAdapter(ArrayList<HomeListItem> dataList, AdapterListener<HomeListItem> listener) {
this.dataList = dataList;
this.listener = listener;
pool = new RecyclerView.RecycledViewPool();
}

@Override
public void onViewRecycled(@NonNull BaseViewHolder holder) {
super.onViewRecycled(holder);
}
@NonNull
@Override
public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == ADS){
return new ADSDataHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_home_ads, parent, false));
}else if (viewType == PIC) {
return new PictureHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_home, parent, false));
}else if (viewType == QUE) {
return new QuestionHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_home, parent, false));
}else
return new DataHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_home, parent, false));
}
@Override
public int getItemViewType(int position) {
if (dataList.get(position).getType() == ContentType.ADS)
return ADS;
if (dataList.get(position).getType() == ContentType.GALLERY)
return PIC;
if (dataList.get(position).getType() == ContentType.LIBS )
return DATA;
return QUE;
}
@Override
public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
if (holder instanceof DataHolder){
((DataHolder) holder).bind(dataList.get(position));
} else if (holder instanceof ADSDataHolder) {
((ADSDataHolder) holder).bind(dataList.get(position));
} else if (holder instanceof PictureHolder) {
((PictureHolder) holder).bind(dataList.get(position));
}else if (holder instanceof QuestionHolder) {
((QuestionHolder) holder).bind(dataList.get(position));
}
}
class ADSDataHolder extends BaseViewHolder {
...
}
class PictureHolder extends BaseViewHolder {
...
}

class QuestionHolder extends BaseViewHolder{
private RecyclerView recyclerView;
private TextView title;
private View more;
public QuestionHolder(View itemView) {
super(itemView);
setType(QUE);
more = itemView.findViewById(R.id.more);
title = itemView.findViewById(R.id.title);
recyclerView = itemView.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(itemView.getContext(),RecyclerView.HORIZONTAL,false));
recyclerView.hasFixedSize();
recyclerView.setRecycledViewPool(pool);
}
public void bind(HomeListItem data) {
Collections.reverse(data.getData());
title.setText(data.getType().getVisibleName());
HomeQuestionAdapter adapter = new HomeQuestionAdapter((ArrayList<MainPageItem>) (ArrayList<?>) data.getData(),
new AdapterListener<MainPageItem>() {
@Override
public void onItemClick(MainPageItem item) {
onListItemClick(itemView.getContext(), data.getType(), item.getItemId());
}
});
recyclerView.setAdapter(adapter);
more.setOnClickListener(v -> listener.onItemClick(data));
}
}
class DataHolder extends BaseViewHolder {
private RecyclerView recyclerView;
private TextView title;
private View more;
DataHolder(View itemView) {
super(itemView);
setType(DATA);
more = itemView.findViewById(R.id.more);
title = itemView.findViewById(R.id.title);
recyclerView = itemView.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(itemView.getContext(),
LinearLayoutManager.HORIZONTAL, true));
recyclerView.hasFixedSize();
recyclerView.setRecycledViewPool(pool);
}
public void bind(HomeListItem data) {
Collections.reverse(data.getData());
title.setText(data.getType().getVisibleName());
SmallItemAdapter adapter = new SmallItemAdapter((ArrayList<MainPageItem>)
(ArrayList<?>) data.getData(),
new AdapterListener<MainPageItem>() {
@Override
public void onItemClick(MainPageItem item) {
onListItemClick(itemView.getContext(), data.getType(), item.getItemId());
}
});
recyclerView.setAdapter(adapter);
recyclerView.scrollToPosition(data.getData().size() - 1);
more.setOnClickListener(v -> listener.onItemClick(data));
}
}
private void onListItemClick(Context context, ContentType contentType, long id) {
// click
}

}

BaseAdapter:

public abstract class BaseAdapter<T> extends RecyclerView.Adapter<BaseViewHolder> {
protected List<T> dataList;
protected final int DATA_TYPE = 1;
protected boolean isLoading = false, isMoreDataAvailable = false;
protected AdapterListener<T> listener;
@Override
public int getItemViewType(int position) {
if (dataList.get(position) == null)
return -1;
else return DATA_TYPE;
}
@Override
public int getItemCount() {
return dataList.size();
}
public void setMoreDataAvailable(boolean isMoreDataAvailable) {
this.isMoreDataAvailable = isMoreDataAvailable;
}
public void removeLoadingItem() {
if (dataList.size() > 0 && dataList.get(dataList.size() - 1) == null) {
dataList.remove(dataList.size() - 1);
notifyItemRemoved(dataList.size() - 1);
}
}
public void notifyDataChanged() {
isLoading = false;
notifyDataSetChanged();
}
}

和BaseViewHolder:

public class BaseViewHolder extends RecyclerView.ViewHolder {
private int type;
public BaseViewHolder(View itemView) {
super(itemView);
}
}

当我滚动回收窗口时,会给我一个错误

我的错误:

:00:26.247 4194-4194/ir.hnfadak.shahidezendeh E/PushPole:Exception caught 
java.lang.ClassCastException: ir.hfadak.fadakmedia.UI.Main.Home.Picture.SmallItemAdapter$DataHolder cannot be cast to ir.hfadak.fadakmedia.UI.Main.Question.HomeQuestionAdapter$DataQueHolder
at ir.hfadak.fadakmedia.UI.Main.Question.HomeQuestionAdapter.onBindViewHolder(HomeQuestionAdapter.java:31)
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.flushTaskWithDeadline(GapWorker.java:345)
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:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6238)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:933)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)

和我的HomeQuestionAdapter


public class HomeQuestionAdapter extends RecyclerView.Adapter<HomeQuestionAdapter.DataQueHolder> {
private RoundedCorners roundedCorners;
protected List<MainPageItem> dataList;
protected final int DATA_TYPE = 1;
protected boolean isLoading = false, isMoreDataAvailable = false;
protected AdapterListener<MainPageItem> listener;

public HomeQuestionAdapter(ArrayList<MainPageItem> dataList, AdapterListener<MainPageItem> listener) {
this.dataList = dataList;
this.listener = listener;
roundedCorners = new RoundedCorners(16);
}

@Override
public int getItemViewType(int position) {
if (dataList.get(position) == null)
return -1;
else return DATA_TYPE;
}
@Override
public int getItemCount() {
return dataList.size();
}
public void setMoreDataAvailable(boolean isMoreDataAvailable) {
this.isMoreDataAvailable = isMoreDataAvailable;
}
public void removeLoadingItem() {
if (dataList.size() > 0 && dataList.get(dataList.size() - 1) == null) {
dataList.remove(dataList.size() - 1);
notifyItemRemoved(dataList.size() - 1);
}
}
public void notifyDataChanged() {
isLoading = false;
notifyDataSetChanged();
}


@NonNull
@Override
public HomeQuestionAdapter.DataQueHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new DataQueHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list_simple_question, parent, false));
}

@Override
public void onBindViewHolder(@NonNull HomeQuestionAdapter.DataQueHolder holder, int position) {
if (!isLoading && isMoreDataAvailable && position >= getItemCount() - 1) {
isLoading = true;
listener.onLoadMore();
} else {
holder.bind(dataList.get(position));
}
}

class DataQueHolder extends RecyclerView.ViewHolder {
private ImageView image;
private ImageView share,faivorid;
private TextView question,answer,view;
DataQueHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.imageQue);
question = itemView.findViewById(R.id.titleQue);
answer = itemView.findViewById(R.id.answerQue);
share = itemView.findViewById(R.id.share);
faivorid = itemView.findViewById(R.id.favorite);
view = itemView.findViewById(R.id.viewtxt);
}
void bind(MainPageItem data) {
Glide.with(itemView)
.load(data.getItemSmallImageAddress())
.apply(bitmapTransform(roundedCorners))
.apply(new RequestOptions().error(R.drawable.img_list_def)
.placeholder(R.drawable.img_list_def))
.into(image);
question.setText(data.getItemTitle());
answer.setText(data.getItemDescription());
share.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ContextUtil.share(itemView.getContext(),
data.getItemTitle() + "nn"
+ data.getItemDescription() + "nn"
+ data.getItemSmallImageAddress());
}
});

itemView.setOnClickListener(v -> listener.onItemClick(data));
}
}
}

代码哪里错了?

您的are类型将超类的实例强制转换为导致此错误的子类的引用。

相反,创建这样的东西:-

public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
if (holder instanceof DataQueHolder){
((DataQueHolder) holder).bind(dataList.get(position));
}else if (holder instanceof DataHolder){
((DataHolder) holder).bind(dataList.get(position));
}else if (holder instanceof ADSDataHolder) {
((ADSDataHolder) holder).bind(dataList.get(position));
} else if (holder instanceof PictureHolder) {
((PictureHolder) holder).bind(dataList.get(position));
}else if (holder instanceof QuestionHolder) {
((QuestionHolder) holder).bind(dataList.get(position));
}
}

请从DataListAdapter
中删除此行

recyclerView.setRecycledViewPool(pool);

它对我有效。

最新更新