RecyclerView项目重复并不断变化

时间:2015-09-24 21:34:51

标签: android android-recyclerview

发生了什么:

滚动时,列表(RecyclerView)正在混合数据。

  

I.E 当我向下滚动后向上滚动时,会重复一些列表项,而不会显示正确的内容。

package jamesnguyen.newzyv2.UI_update;

import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

import jamesnguyen.newzyv2.R;
import jamesnguyen.newzyv2.RSS_Processcors.RssItem;

public class RVAdapter extends RecyclerView.Adapter<RVAdapter.FeedViewHolder> {

    private static List<RssItem> items = null;
    private static Context context;

    public RVAdapter(Context context, List<RssItem> items) {
        this.items = items;
        this.context = context;
    }

    public static List<RssItem> getItems() {
        return items;
    }

    @Override
    public RVAdapter.FeedViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
        return new FeedViewHolder(v);
    }

    @Override
    public void onBindViewHolder(RVAdapter.FeedViewHolder holder, int position) {
        FeedViewHolder.getTitle().setText(items.get(position).getTitle());
        FeedViewHolder.getPubDate().setText(items.get(position).getPubDate());
        //FeedViewHolder.getDescription().setText(items.get(position).getDescription());
    }

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

    @Override
    public int getItemCount() {
        return items.size();
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    public static class FeedViewHolder extends RecyclerView.ViewHolder {
        private static CardView cv;
        private static TextView title;
        private static TextView pubDate;
        private static TextView description;

        FeedViewHolder(View itemView) {
            super(itemView);
            cv = (CardView) itemView.findViewById(R.id.cv);
            title = (TextView) itemView.findViewById(R.id.title);
            pubDate = (TextView) itemView.findViewById(R.id.pubDate);
            //description = (TextView) itemView.findViewById(R.id.description);
        }

        public static TextView getTitle() {
            return title;
        }

        public static TextView getPubDate() {
            return pubDate;
        }

        public static TextView getDescription() {
            return description;
        }
    }
}

我相信也许有些工作必须通过RecyclerView的回收过程来完成,但我试过看起来没什么可行的。

10 个答案:

答案 0 :(得分:38)

完成。

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

@Override
public int getItemViewType(int position) {
   return position;
}

答案 1 :(得分:33)

RecyclerView适配器中只有两件事

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

并在适配器

的构造函数中
 setHasStableIds(true);

希望它有所帮助!

答案 2 :(得分:17)

像这样覆盖Adapter类中的这些方法。

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

@Override
public int getItemViewType(int position) {
 return position;
}

答案 3 :(得分:6)

问题是CardViewTextView对象在FeedViewHolder内被声明为静态。这意味着尝试在onBindViewHolder方法中设置标题的所有调用都会触及最新的膨胀视图。

修复方法是从staticcvtitlepubDate中移除description,然后实现一些非静态设置器,如:

public void setTitle(String s) {
    title.setText(s);
}

要在onBindViewHolder方法中调用:

@Override
public void onBindViewHolder(RVAdapter.FeedViewHolder holder, int position) {
    holder.setTitle(items.get(position).getTitle());
    //...
}

答案 4 :(得分:3)

我对大型网格recyclerview遇到同样的问题,该视图具有按顺序应出现的数百个数字,但是它们的顺序混乱并重复。

// More concise code with Kotlin expressions
override fun getItemId(position: Int) = position.toLong()
override fun getItemViewType(position: Int) = position

在适配器上添加了以上几行。

答案 5 :(得分:2)

在Kotlin中,从RecyclerView中清除LinearLayout列表项中的先前项目

max

答案 6 :(得分:2)

只需添加

override fun getItemViewType(position: Int): Int {
     return position
}

答案 7 :(得分:1)

如果有人使用Kotlin,请在RecyclerView.Adapter内部使用

setHasStableId(true)将应用于RecylerView的适配器

 init {
        setHasStableIds(true);
    }

使用产品ID覆盖职位

override fun getItemId(position: Int): Long {
        return myList?.get(position).id
    }

答案 8 :(得分:0)

使用holder.setIsRecyclable(false);在适配器类的onBindViewHolder中

答案 9 :(得分:0)

这个问题可能很老了,但有些信息没有透露。 我遇到了类似的问题并偶然发现了这个问题。经过数周的研究,我意识到最重要的

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

@Override
    public int getItemViewType(int position) {
    return position;
}

没有帮助我(它可能会帮助另一个人)。

问题是视图被回收了。但这不是问题,因为这是 recyclerview 的主要本质。所以,这是修复

override fun onViewRecycled(holder: ViewHolder) {
    super.onViewRecycled(holder)

    holder.title.setText(null)
}

当视图被回收时,它的 viewholder 仍然具有它使用位置的先前值。如果 (items.get(position).getTitle() 返回一个值,它会正确重置 title 的文本值,否则如果它返回 null,它会保留回收视图中的值。因此,我刚刚向您展示的示例在回收视图时将标题的文本值重置为 null