1

我在这里遵循了这个例子:https ://developer.android.com/training/material/lists-cards.html

发生了什么

当我滚动时,列表(RecyclerView)正在混淆数据。即当我向下滚动后向上滚动时,某些列表项会重复,不显示正确的内容。

这是我的onBindViewHolder方法:

// cardsData is a List of MyCardItem (MyCardItem is just a holder of information,
// such as an id, String title, String summary, and other info to display on a card
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position)
{
    // Update view here
    if (!cardsData.isEmpty())
    {
        viewHolder.updateDisplay(cardsData.get(position), activity, position);
    }
}

这是我updateDisplay在 ViewHolder 类中找到的方法:

// Set ID
if (item.getID() != null)
{
    mIDView.setText(item.getID());
}

// Set Title
if (item.getTitle() != null)
{
    mTitleView.setText(item.getTitle());
}

// Set Summary
if (item.getSummary() != null)
{
    mSummaryView.setText(Html.fromHtml(item.getSummary()));
}

// Image
if (item.hasImage())
{
    // Display image here
}

我相信这有时数据为空的事实有关,所以我选择不显示它。并非所有项目(卡片)都会显示图像,所以这就是我检查项目是否应该有图像的原因。如果是这样,那么我会做一些花哨的代码来显示图像(并制作其他视图GONE,以便我只能显示该图像等)。

在调试时,我强制所有卡片在标题中显示它们的 ID 和位置。我可以确认所有 id 和位置在适当的位置。当我强制(删除对 id、title 和 summary 的 if 检查)id、title 和 summary 显示时,即使为空,该内容也不受影响。但是,这并不能解决我的图像情况(并不总是有图像)。然后,我将有一些图像占据某个 id/位置的位置,它不应该出现在该位置(即,它不显示摘要文本,而是显示不应该存在的图像)。

关于为什么在我的 RecyclerView 中发生这种情况的任何输入?

4

5 回答 5

12

RecyclerView,就像ListViewand一样GridView,尽可能重用视图。这意味着当您滚动时,从顶部掉下来的视图将用于底部的视图等。这大大提高了内存效率和滚动性能。这意味着如果您不重置新项目的所有状态,您将看到上次使用此视图时剩余的状态。

相反,您应该始终重置所有状态:

if (item.getID() != null) {
  mIDView.setText(item.getID());
} else {
  mIDView.setText("");
}
// etc...

此外,不应该有任何需要检查的情况cardsData.isEmpty()- 相反,每当您更新时cardsData,您应该调用适当的notifyXXX方法(例如notifyItemInserted()或更糟糕的情况下notifyDataSetChanged()),它将自动刷新列表适当地。

于 2014-10-27T03:25:03.217 回答
4

实施

public long getItemId(int position) {}

否则,您会在RecyclerView中看到重复的项目。

于 2015-04-07T08:08:12.987 回答
3

添加这两个,你很高兴!

@Override
public long getItemId(int position) {
    return position;
}

@Override
public int getItemViewType(int position) {
   return position;
}
于 2016-12-16T20:15:13.517 回答
1

除了先前的答案之外,您还可以检查空虚视图,例如:

if (TextUtils.isEmpty(viewHolder.item.getText())) {
        viewHolder.item.setText(object.getItem());
    }
于 2014-12-05T11:14:43.367 回答
0

详细说明 ViliusK 的答案。此实现将起作用:

@Override
public long getItemId(int position) {
    Object obj = getItemAtPosition(position);
    return obj.hashCode();
}
于 2016-09-22T04:15:06.093 回答