Android RecyclerView.Adapter-显示的数据不正确
我在使用RecyclerView.Adapter时遇到了一些困难。问题在于,RecyclerView有时会混淆视图,但不会混淆底层数据,而是混淆显示内容。它只发生在屏幕上大约5%的项目上。有时TextView完全从外部空间获取文本,例如,它假设显示“1”,但显示“50”,但该数字在应用程序中的任何位置都不存在,因为在我创建项目时文本是自动递增的,我有两个,另外,当我检查数据库中的哪些项目在哪个位置上一切正常时,更奇怪的是,当我调试onBindViewHolder时,holder获得了所有正确的数据,并将其设置为视图,但屏幕得到了一些不同的结果,因此错误似乎是在onBindViewHolder之后的某个位置生成的。需要明确的是,我正确地实现了所有方法getItemId、HassTableId和getItem,它们确实为onBindViewHolder中的给定位置返回了正确的项Android RecyclerView.Adapter-显示的数据不正确,android,android-recyclerview,Android,Android Recyclerview,我在使用RecyclerView.Adapter时遇到了一些困难。问题在于,RecyclerView有时会混淆视图,但不会混淆底层数据,而是混淆显示内容。它只发生在屏幕上大约5%的项目上。有时TextView完全从外部空间获取文本,例如,它假设显示“1”,但显示“50”,但该数字在应用程序中的任何位置都不存在,因为在我创建项目时文本是自动递增的,我有两个,另外,当我检查数据库中的哪些项目在哪个位置上一切正常时,更奇怪的是,当我调试onBindViewHolder时,holder获得了所有正确的数
@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");
}
}
好的,解决方案是这样的,我忘了从ViewHolder中的checklistItemsLayout中删除所有视图,这会使我显示的两种项目中的一种膨胀,因此每次特定的ViewHolder被重用时,文本视图都被正确添加,但它们被堆叠在旧视图上,因此没有空间显示,但只有在同一类型的项目上重用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)
{
...
}
}
}
@覆盖
BindViewHolder上的公共无效(ItemViewHolder,int位置){
...
开关(项目类型){
案例常数注:
holder.noteText.setText(item.note.text);
holder.checklistItemsLayout.removeAllViews();
holder.checklistLines.setImageBitmap(null);
holder.noteText.setTextSize(屏幕宽度*常数网格\文本\大小\道具);
holder.noteText.setPadding(paddingHorizontal、paddingVertical、paddingHorizontal、paddingVertical);
打破
案例施工检查表:
//这条线不见了
holder.checklistItemsLayout.removeAllViews();
holder.noteText.setText(null);
holder.checklistItemsLayout.setPadding(水平填充、垂直填充、水平填充、垂直填充);
Iterator it=item.checklist.checklistItems.Iterator();
int i=0;
while(it.hasNext()&&i<4)
{
...
}
}
}
好的,解决方案是,我忘了从ViewHolder中的checklistItemsLayout中删除所有视图,这会使我显示的两种类型的项目之一膨胀,因此每次特定的ViewHolder被重用时,文本视图都被正确添加,但它们被堆叠在旧的视图上,因此没有空间显示,但只有在同一类型的项目上重用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)
{
...
}
}
}
@覆盖
BindViewHolder上的公共无效(ItemViewHolder,int位置){
...
开关(项目类型){
案例常数注:
holder.noteText.setText(item.note.text);
holder.checklistItemsLayout.removeAllViews();
holder.checklistLines.setImageBitmap(null);
holder.noteText.setTextSize(屏幕宽度*常数网格\文本\大小\道具);
holder.noteText.setPadding(paddingHorizontal、paddingVertical、paddingHorizontal、paddingVertical);
打破
案例施工检查表:
//这条线不见了
holder.checklistItemsLayout.removeAllViews();
holder.noteText.setText(null);
holder.checklistItemsLayout.setPadding(水平填充、垂直填充、水平填充、垂直填充);
Iterator it=item.checklist.checklistItems.Iterator();
int i=0;
while(it.hasNext()&&i<4)
{
...
}
}
}
@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)
{
...
}
}
}