我在使用RecyclerView.Adapter时遇到了一些麻烦。问题是RecyclerView有时会混淆视图,但不会与底层数据混合,而是显示内容。它只发生在屏幕上大约5%的项目上。有时TextViews完全从外部空间获取文本,例如它假设显示“1”但显示“50”但该数字在应用程序中的任何位置都不存在,因为文本在我创建项目时自动增量而且我已经得到了两个,当我检查数据库中的哪些项目在哪个位置一切都很好,什么更多的时候,当我调试onBindViewHolder时,持有者获得了所有正确的数据,并将其设置为视图,但是屏幕有所不同,所以看起来错误是在onBindViewHolder之后的某个地方生成的。为了清楚起见,我正在实现所有方法getItemId,hasStableIds,getItem,它们确实为onBindViewHolder中的给定位置返回正确的项目。
@Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
Item item = mProvider.getItem(position);
int stickerSize = (int) (screenWidth * Const.STICKER_GRID_PROP);
Picasso.with(mContext)
.load(Const.backgroundNoteIDs[item.backgroundId])
.into(holder.background);
Picasso.with(mContext)
.load(Const.stickerIDs[item.stickerId])
.resize(stickerSize, stickerSize)
.centerInside()
.into(holder.sticker);
int paddingHorizontal = (int) (screenWidth * Const.GRID_TEXT_PADDING_HORIZONTAL_PROP);
int paddingVertical = (int) (screenWidth * Const.GRID_TEXT_PADDING_VERTICAL_PROP);
switch(item.type) {
case Const.NOTE:
holder.noteText.setText(item.note.text);
holder.checklistItemsLayout.removeAllViews();
holder.checklistLines.setImageBitmap(null);
holder.noteText.setTextSize(screenWidth * Const.GRID_TEXT_SIZE_PROP);
holder.noteText.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical);
break;
case Const.CHECKLIST:
holder.noteText.setText(null);
holder.checklistItemsLayout.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical);
Iterator<ChecklistItem> it = item.checklist.checklistItems.iterator();
int i = 0;
while(it.hasNext() && i < 4)
{
ChecklistItem checklistItem = it.next();
final TextView textView = new TextView(mContext);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setText(checklistItem.text);
int drawable;
if(checklistItem.checkStatement) {
drawable = R.drawable.checked;
} else {
drawable = R.drawable.unchecked;
}
Picasso.with(mContext)
.load(drawable)
.resize((int) (stickerSize * 0.25f), (int) (stickerSize * 0.25f))
.centerInside()
.into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Drawable d = new BitmapDrawable(mResources, bitmap);
textView.setCompoundDrawablesWithIntrinsicBounds(d, null, null, null);
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
Picasso.with(mContext)
.load(R.drawable.karteczka_linie)
.resize( (int) (screenWidth * Const.MENU_BIG_BUTTON_PROP), (int) (screenWidth * Const.MENU_BIG_BUTTON_PROP))
.centerInside()
.into(holder.checklistLines);
textView.setTextSize(screenWidth * Const.GRID_TEXT_SIZE_PROP);
holder.checklistItemsLayout.addView(textView);
i++;
}
break;
default:
throw new IllegalArgumentException("onBindViewHolder got item without any type");
}
}
public Item getItem(int index) {
return mItems.get(index);
}
public static class ItemViewHolder extends RecyclerView.ViewHolder implements
ItemTouchHelperViewHolder {
public TextView noteText;
public ImageView background;
public ImageView checklistLines;
public ImageView sticker;
public LinearLayout checklistItemsLayout;
public ItemViewHolder(View itemView) {
super(itemView);
noteText = (TextView) itemView.findViewById(R.id.note_text);
background = (ImageView) itemView.findViewById(R.id.note_background);
checklistLines = (ImageView) itemView.findViewById(R.id.checklist_lines);
sticker = (ImageView) itemView.findViewById(R.id.note_sticker);
checklistItemsLayout = (LinearLayout) itemView.findViewById(R.id.checklist_items);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick " + getItemId());
}
});
}
@Override
public void onItemSelected() {
itemView.setBackgroundColor(Color.LTGRAY);
}
@Override
public void onItemClear() {
itemView.setBackgroundColor(0);
}
}
答案 0 :(得分:0)
Okey,所以这是解决方案,我忘了从ViewHolder中的checklistItemsLayout中删除所有视图,这会扩展我显示的两种类型的项目之一,因此每次特定的 ViewHolder被重用,TextViews是添加得当但是它们堆叠在旧的上面,所以它们没有空间显示,但只有当ViewHolder在相同类型的项目上重复使用时才会发生这种情况。
您需要记住在onBindViewHolder中重新加载ViewHolder中的每个元素,否则您可能会像之前在此ViewHolder中使用的其他项目中剩余一些剩余部分
这是固定代码:
@Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
...
switch(item.type) {
case Const.NOTE:
holder.noteText.setText(item.note.text);
holder.checklistItemsLayout.removeAllViews();
holder.checklistLines.setImageBitmap(null);
holder.noteText.setTextSize(screenWidth * Const.GRID_TEXT_SIZE_PROP);
holder.noteText.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical);
break;
case Const.CHECKLIST:
//This line was missing
holder.checklistItemsLayout.removeAllViews();
holder.noteText.setText(null);
holder.checklistItemsLayout.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical);
Iterator<ChecklistItem> it = item.checklist.checklistItems.iterator();
int i = 0;
while(it.hasNext() && i < 4)
{
...
}
}
}