Страницы

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

воскресенье, 22 декабря 2019 г.

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

#java #android #adapter #recyclerview


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

    

На втором фото, есть элемент с картинкой игры нхл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);
        }
    }
 }


Может кто то сталкивался с данной проблемой?
    


Ответы

Ответ 1



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

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

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