Strange behaviour of images in RecyclerView

后端 未结 3 1054
忘掉有多难
忘掉有多难 2020-12-23 09:52

I am using android.support.v7.widget.RecyclerView to show simple items containing text and in some cases also images. Basically I followed the tutorial from here https://dev

相关标签:
3条回答
  • 2020-12-23 10:32

    Based on @Lion789's answer. I'm using Google's Volley for image and json loading.

    This allows us to retrieve the position on the view that's going to be recycled later.

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

    When making the request, set the position as the TAG

    @Override
    public void onBindViewHolder(final ItemHolder holder, int position) {
            ImageRequest thumbnailRequest = new ImageRequest(url,
                    new Response.Listener<Bitmap>() {
                        @Override
                        public void onResponse(Bitmap response) {                          
                            holder.itemThumbnail.setImageBitmap(response);
                        }
                    },[...]);
    
            thumbnailRequest.setTag(String.valueOf(position)); //setting the TAG
            mQueue.addToRequestQueue(thumbnailRequest);
    }
    

    And when the view is being recycled we'll cancel the request, and remove the current image

    @Override
    public void onViewRecycled(ItemHolder holder) {
        super.onViewRecycled(holder);
        mQueue.cancelAll(String.valueOf(holder.getItemViewType()));
        holder.itemThumbnail.setImageDrawable(null);
    }
    

    Volley garanties that canceled requests won't be delivered.

    0 讨论(0)
  • 2020-12-23 10:36

    I think you need to add an else clause to your if ( object.has("image") ) statement in the onBindViewHolder(ViewHolder holder, int position) method, setting the image to null:

    holder.image.setImageDrawable(null);
    

    I think the documentation for onBindViewHolder describe it best why this is necessary:

    Called by RecyclerView to display the data at the specified position. This method should update the contents of the itemView to reflect the item at the given position.

    You should always assume that the ViewHolder passed in needed to be completely updated :)

    0 讨论(0)
  • 2020-12-23 10:37

    Not sure if people still have issues with this, but the if statement did not work for me. What did work for me is this:

    Using an override on this method in the adapter

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

    followed by calling the if statement based on this for the image itself within the onBindViewHolder, like so:

    int pos = getItemViewType(position);
                if(theList.get(pos).getPicture() == null) {
    
                    holder.picture.setVisibility(View.GONE);
                } else {
    
                    Picasso.with(context).load(R.drawable.robot).into(holder.picture);
                }
    

    I am using Picasso but it should work with any other else situation. Hope this helps someone!

    0 讨论(0)
提交回复
热议问题