Glide: Image size change in RecycleView

Created on 24 Nov 2016  路  5Comments  路  Source: bumptech/glide


Glide Version:
com.github.bumptech.glide:glide:3.7.0


Integration libraries:
'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar'


Device/Android Version:
Galaxy S6,Also this issue is happen in huawei mt7 and 5.1WVGA api23


Issue details / Repro steps / Use case background:
I am using Glide load image in recycleview,I have two types of ViewHolders.When I scrolling the recycleview,The image size will change,sometimes change from very small to bigger every time I scroll. .The issue has alread discussed in stackoverflow.But I have a new clue. When the imageview has padding,this issue will happen.When I remove the padding,The issue is gone.


Glide load line / GlideModule (if any) / list Adapter code (if any):
In Adapter, onBindViewHolder:

if(msg.getContentType().trim().equals(Constants.message_contentType_text)) {
                    ((MsgToHolder) holder).tv_msg_to.setText(msg.getContent());
                    ((MsgToHolder) holder).tv_msg_to.setVisibility(View.VISIBLE);
                    ((MsgToHolder) holder).imageview.setImageDrawable(null);
                    ((MsgToHolder) holder).imageview.setVisibility(View.GONE);
                }else if(msg.getContentType().trim().equals(Constants.message_contentType_image)){
                    ((MsgToHolder) holder).tv_msg_to.setText("");
                    ((MsgToHolder) holder).tv_msg_to.setVisibility(View.GONE);
                    ((MsgToHolder) holder).imageview.setVisibility(View.VISIBLE);
     Glide.with(getActivity()).load(Constants.host+msg.getContent()).override(width,height).into(((MsgToHolder) holder).imageview);
                    ((MsgToHolder) holder).imageview.setOnClickListener(new OnClickImageListener(position));
                }


Layout XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="right">

    <FrameLayout
        android:id="@+id/fl_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/chat_to_bg">
        <TextView
            android:id="@+id/tv_msg_to"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginBottom="12dp"
            android:layout_marginTop="12dp"
            android:textSize="@dimen/textSize_normal"
            android:textColor="@color/white_text"/>
        <ImageView
            android:id="@+id/imageview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="1dp"
            android:adjustViewBounds="true"
            android:maxWidth="230dp"/>
    </FrameLayout>



    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/img_horn_blue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="-6dp"
            android:src="@drawable/img_horn_blue"/>

        <ImageView
            android:id="@+id/iv_head_to"
            android:layout_width="35dp"
            android:layout_height="35dp"
            android:src="@drawable/defult_user_avatar"
            android:layout_toRightOf="@id/img_horn_blue"/>
    </RelativeLayout>

</LinearLayout>
question

All 5 comments

Let's see:

  • Which stackoverflow question are you mentioning?
  • Glide doesn't support wrap-wrap, that's why you're forced to use .override().
  • imageview.setImageDrawable(null) is not safe (leaks and stuff), use Glide.clear(holder.imageview) to reclaim ownership of the view
  • also make sure you start a new load into the image view, or clear the image view in all branches, that is: add an else branch. If that can "never happen", throw an exception in the else, so if it happens you'll immediately know what's wrong.
  • setOnClickListener gets stale if an item is recycled and re-used for the other content type (not sure if you're using RecyclerView item-types here).
  • padding on ImageView is not supported if you want to use Glide to load the image

Thanks for response my question so quick. I edited my code as follow:

@Override
        public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
            if (holder instanceof MsgToHolder) {
                final Message.Msg msg = msgList.get(position);
                if (!StringUtil.isBlank(PlantsProApplication.getUser().getProfthumb())) {
                    Glide.with(ChatDF.this).load(Constants.host + PlantsProApplication.getUser().getProfthumb()).transform(new GlideCircleTransform(getActivity())).into(((MsgToHolder) holder).iv_head_to);
                } else {
                    ((MsgToHolder) holder).iv_head_to.setImageResource(R.drawable.defult_user_avatar);
                }
                Glide.clear(((MsgToHolder) holder).imageview);
                if (msg.getContentType().trim().equals(Constants.message_contentType_text)) {
                    ((MsgToHolder) holder).tv_msg_to.setText(msg.getContent());
                    ((MsgToHolder) holder).tv_msg_to.setVisibility(View.VISIBLE);
                    ((MsgToHolder) holder).imageview.setOnClickListener(null);
                    ((MsgToHolder) holder).imageview.setVisibility(View.GONE);
                } else if (msg.getContentType().trim().equals(Constants.message_contentType_image)) {
                    ((MsgToHolder) holder).tv_msg_to.setText("");
                    ((MsgToHolder) holder).tv_msg_to.setVisibility(View.GONE);
                    ((MsgToHolder) holder).imageview.setVisibility(View.VISIBLE);
                    Glide.with(getActivity()).load(Constants.host + msg.getContent()).override(width, height).into(((MsgToHolder) holder).imageview);
                    ((MsgToHolder) holder).imageview.setOnClickListener(new OnClickImageListener(position));
                }else {
                    //throw exception 
                }
            } else if (holder instanceof MsgFromHolder) {
                final Message.Msg msg = msgList.get(position);
                if (!StringUtil.isBlank(toUser.getProfthumb())) {
                    Glide.with(ChatDF.this).load(Constants.host + toUser.getProfthumb()).transform(new GlideCircleTransform(getActivity())).into(((MsgFromHolder) holder).iv_head_from);
                } else {
                    ((MsgFromHolder) holder).iv_head_from.setImageResource(R.drawable.defult_user_avatar);
                }
                Glide.clear(((MsgFromHolder) holder).imageview);
                if (msg.getContentType().trim().equals(Constants.message_contentType_text)) {
                    ((MsgFromHolder) holder).tv_msg_from.setText(msg.getContent());
                    ((MsgFromHolder) holder).tv_msg_from.setVisibility(View.VISIBLE);
                    ((MsgFromHolder) holder).imageview.setOnClickListener(null);
                    ((MsgFromHolder) holder).imageview.setVisibility(View.GONE);
                } else if (msg.getContentType().trim().equals(Constants.message_contentType_image)) {
                    ((MsgFromHolder) holder).tv_msg_from.setText("");
                    ((MsgFromHolder) holder).tv_msg_from.setVisibility(View.GONE);
                    ((MsgFromHolder) holder).imageview.setVisibility(View.VISIBLE);
                    Glide.with(getActivity()).load(Constants.host + msg.getContent()).override(width, height).into(((MsgFromHolder) holder).imageview);
                    ((MsgFromHolder) holder).imageview.setOnClickListener(new OnClickImageListener(position));
                }else {
                    //throw exception 
                }
            }
        }

setOnClickListener have been set to null. Also to make sure start a new load,I use Glide.clear(holder.imageview) before it load. Add a else branch to throw an exception as you said. Is this the correct way as you said?

You only need to clear when there's no image, and you want to do something to the ImageView yourself. .into() already clears. Consider this:

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
    if (viewHolder instanceof MsgToHolder) {
        final Message.Msg msg = msgList.get(position);
        final MsgToHolder holder = (MsgToHolder)viewHolder;
        if (!StringUtil.isBlank(PlantsProApplication.getUser().getProfthumb())) {
            Glide.with(ChatDF.this)
                 .load(Constants.host + PlantsProApplication.getUser().getProfthumb())
                 .transform(new GlideCircleTransform(getActivity()))
                 .into(holder.iv_head_to);
        } else {
            Glide.clear(holder.iv_head_to); // reclaim in case it was recycled
            holder.iv_head_to.setImageResource(R.drawable.defult_user_avatar);
        }
        if (msg.getContentType().trim().equals(Constants.message_contentType_text)) {
            holder.tv_msg_to.setText(msg.getContent());
            holder.tv_msg_to.setVisibility(View.VISIBLE);
            holder.imageview.setOnClickListener(null);
            holder.imageview.setVisibility(View.GONE);
            Glide.clear(holder.imageview);
        } else if (msg.getContentType().trim().equals(Constants.message_contentType_image)) {
            holder.tv_msg_to.setText("");
            holder.tv_msg_to.setVisibility(View.GONE);
            holder.imageview.setOnClickListener(new OnClickImageListener(position));
            holder.imageview.setVisibility(View.VISIBLE);
            Glide.with(getActivity())
                 .load(Constants.host + msg.getContent())
                 .override(width, height)
                 .into(holder.imageview);
        } else {
            throw new IllegalStateException("Unknown content type: '" + msg.getContentType() + "'");
        }
    } else if (viewHolder instanceof MsgFromHolder) {
        final Message.Msg msg = msgList.get(position);
        final MsgFromHolder holder = (MsgFromHolder)viewHolder;
        if (!StringUtil.isBlank(toUser.getProfthumb())) {
            Glide.with(ChatDF.this)
                 .load(Constants.host + toUser.getProfthumb())
                 .transform(new GlideCircleTransform(getActivity()))
                 .into(holder.iv_head_from);
        } else {
            Glide.clear(holder.iv_head_from); // reclaim in case it was recycled
            holder.iv_head_from.setImageResource(R.drawable.defult_user_avatar);
        }
        if (msg.getContentType().trim().equals(Constants.message_contentType_text)) {
            holder.tv_msg_from.setText(msg.getContent());
            holder.tv_msg_from.setVisibility(View.VISIBLE);
            holder.imageview.setOnClickListener(null);
            holder.imageview.setVisibility(View.GONE);
            Glide.clear(holder.imageview);
        } else if (msg.getContentType().trim().equals(Constants.message_contentType_image)) {
            holder.tv_msg_from.setText("");
            holder.tv_msg_from.setVisibility(View.GONE);
            holder.imageview.setOnClickListener(new OnClickImageListener(position));
            holder.imageview.setVisibility(View.VISIBLE);
            Glide.with(getActivity())
                 .load(Constants.host + msg.getContent())
                 .override(width, height)
                 .into(holder.imageview);
        } else {
            throw new IllegalStateException("Unknown content type: '" + msg.getContentType() + "'");
        }
    } else {
        throw new IllegalStateException("Unknown ViewHolder type " + viewHolder.getClass() + " bound as " + viewHolder);
    }
}

Did you actually solve the original issue?

issue solved!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

billy2271 picture billy2271  路  3Comments

MrFuFuFu picture MrFuFuFu  路  3Comments

Anton111111 picture Anton111111  路  3Comments

sergeyfitis picture sergeyfitis  路  3Comments

kenneth2008 picture kenneth2008  路  3Comments