Страницы

Поиск по вопросам

пятница, 16 ноября 2018 г.

RecyclerView Adapter отображение элементов при быстром скролинге

У меня такая проблема: при быстром скролинге данные клонируются с одних элементов в другие. Извините за большие картинки. На первом фото есть первый элемент с текстом "Новый ПРАЙС!!". Как видите, в нем нет картинки.

На втором фото, есть элемент с картинкой игры нхл15

Но при быстрой прокрутке списке вниз а потом вверх в первом(в текущем случае в первом, а в общем каждый раз куда попадет) элементе появляется картинка со второго фото

Для отображение данных в RecyclerView я использую RecyclerView.Adapter
Код адаптера
public class PostAdapter extends RecyclerView.Adapter {
private RecyclerView listView; VKList posts; Context context;
PostAdapter(VKList p , Context context){ this.posts = p; this.context = context; mInflater = LayoutInflater.from(context); }
private LayoutInflater mInflater; public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = mInflater.inflate(R.layout.simple_list_item_1, viewGroup, false); ViewHolder h = new ViewHolder(v); return h; }
public void onBindViewHolder(final ViewHolder h, final int i) { final VKApiPost post = this.posts.get(i);
h.id.setText("#" + Integer.toString(post.id));
h.date.setText(new SimpleDateFormat("d MMM yyyy 'в' HH:mm", new Locale("ru")) .format(new Date(post.date * 1000L)));
if (post.text != "") { h.content.setVisibility(View.VISIBLE); h.content.setText(post.text); }else{ h.content.setVisibility(View.GONE); }
h.likeCount.setOnClickListener(new View.OnClickListener() { private boolean stateChanged;
public void onClick(View view) { if (stateChanged) { // reset background to default; h.likeCount.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_post_btn_like_up, 0); h.likeCount.setTextColor(Color.DKGRAY); } else { h.likeCount.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_post_btn_like_selected, 0); h.likeCount.setTextColor(Color.BLUE); } stateChanged = !stateChanged; } });
h.comment.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) { Intent commentActivity = new Intent(context, CommentsActivity.class); commentActivity.putExtra("post", post); context.startActivity(commentActivity); } });
if(!post.user_likes) { h.likeCount.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_post_btn_like_up, 0); h.likeCount.setTextColor(Color.DKGRAY); } else { h.likeCount.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_post_btn_like_selected, 0); h.likeCount.setTextColor(Color.BLUE); }
if(post.likes_count == 0) h.likeCount.setText(""); else { h.likeCount.setText(post.likes_count + " "); }
for(int j = 0; j < post.attachments.size(); j++){
VKAttachments.VKApiAttachment att = post.attachments.get(j); String type = att.getType(); if(type == "audio") {
} else if(type == "doc"){ try { h.docLayout.setVisibility(View.VISIBLE);
VKApiDocument doc = (VKApiDocument) att;
h.docName.setText(doc.title); if (doc.size % 1024 != 0) { h.docInfo.setText("Документ " + Long.toString(doc.size / 1024 + 1) + " кб"); } else { h.docInfo.setText("Документ " + Long.toString(doc.size / 1024) + " кб"); } } catch (Exception e){
} } else if(type == "photo"){ VKApiPhoto photo = (VKApiPhoto)att; h.photo.setVisibility(View.VISIBLE);
Picasso.with(this.context).load(photo.photo_604).into(h.photo); } } }
@Override public int getItemCount() { return this.posts.size(); }
@Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); }
static class ViewHolder extends RecyclerView.ViewHolder{ TextView id; TextView date; TextView content; ResizableImageView photo; CardView cv; RecyclerView audios;
TextView likeCount;
TextView docName; TextView docInfo; LinearLayout docLayout;
Button comment;
ViewHolder(View itemView){ super(itemView); cv = (CardView)itemView.findViewById(R.id.cv); id = (TextView)itemView.findViewById(R.id.postId); content = (TextView)itemView.findViewById(R.id.postContent); photo = (ResizableImageView)itemView.findViewById(R.id.postImage); date = (TextView)itemView.findViewById(R.id.postDate); audios = (RecyclerView) itemView.findViewById(R.id.postAudioList); comment = (Button) itemView.findViewById(R.id.btnComment); likeCount = (TextView) itemView.findViewById(R.id.likeCount);
docLayout = (LinearLayout) itemView.findViewById(R.id.HLRelativeLayout1); docName = (TextView) itemView.findViewById(R.id.docs_item_title); docInfo = (TextView) itemView.findViewById(R.id.docs_item_info); } } }
Может кто то сталкивался с данной проблемой?


Ответ

При прокрутке вниз создаются новые вьюхи, выполняется onCreateViewHolder() и onBindViewHolder(). Ушедшие при скролле за экран вьюхи не уничтожаются, а перемещаются в пул объектов RecycledViewPool. Затем, при скролле вверх, либо при дальнейшем скролле вниз, новые вьюхи уже не создаются, а используются ранее освобожденные. Вьюха берётся из RecycledViewPool и вызывается только onBindViewHolder(). В вашем onBindViewHolder() в некоторых случаях не инициализируется h.photo, поэтому там показывается старое значение.
В onBindViewHolder() нужно всегда полностью инициализировать все элементы, которые могут изменяться. Т.е. нужно добавить h.photo.setVisibility(View.GONE) куда-нибудь в начало onBindViewHolder(), либо дальше в условиях.

Комментариев нет:

Отправить комментарий