Picasso Library:ListView中的ImageView在快速Scroll上多次显示加载图像

时间:2015-02-25 07:31:38

标签: android image android-listview imageview picasso

我正在使用picaso回调将远程图像加载到listView行中。但是当listView滚动得非常快时,图像会多次更改。我猜它是由于行重用。如何在不重新加载imageView中的不同图像的情况下更正并显示正确的图像。

我还将null位图设置为ImageView。因此在重用图像时不会使用以前的图像

这是我的代码:

      @Override
public View getView(int position, View convertView, ViewGroup arg2)
{
    ViewHolder holder = null;

    if (convertView == null)
    {
        LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = vi.inflate(R.layout.row_health, arg2, false);
        holder = new ViewHolder();

        convertView.setTag(holder);

    }

    else
    {
        holder = (ViewHolder) convertView.getTag();

        holder.imageOfDoctor_select.setImageBitmap(null);

    }
  loadImage("imageViewURL", relLyt_txtPicInitials, imgVw);
}


 private void loadImage(String imgURL, RoundedImage imgVw, RelativeLayout relLyt_txtPicInitials){

 Target target = new Target() {
        @Override
        public void onBitmapFailed(Drawable arg0)
        {
            // TODO Auto-generated method stub

        }

        @Override
        public void onPrepareLoad(Drawable arg0)
        {
            // TODO Auto-generated method stub

        }

        @Override
        public void onBitmapLoaded(Bitmap bitmap, LoadedFrom arg1)
        {
            if(bitmap != null){
                imgVw.setVisibility(View.VISIBLE);
                imgVw.setImageBitmap(bitmap);
                relLyt_txtPicInitials.setVisibility(View.GONE);
            }


        }
    };
    if (!TextUtils.isEmpty(imgURL) && !imgURL.equalsIgnoreCase("null") && URLUtil.isValidUrl(imgURL))
    {
        Picasso.with(context).load(imgURL).into(target);
    }

  }

RoundedImage.java

  public class RoundedImage extends ImageView
 {

private float cornerRadius;
private float bitmapCornerRadius;

public RoundedImage(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);
    getXMLAttribute(context, attrs);

    // TODO Auto-generated constructor stub
   }




            public RoundedImage(Context context, AttributeSet attrs)
      {
    super(context, attrs);
    getXMLAttribute(context, attrs);

    // TODO Auto-generated constructor stub
}

public RoundedImage(Context context)
{
    super(context);
    // TODO Auto-generated constructor stub
}

@Override
public void setImageBitmap(Bitmap bm)
{
    if (bm != null)
    {
        bm = Utils.getRoundedCornerBitmap(bm, 50);
    }
    super.setImageBitmap(bm);
}

private void getXMLAttribute(Context context, AttributeSet attrs)
{
    // Get proportion.
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedCornerImageView);
    cornerRadius = a.getDimension(R.styleable.RoundedCornerImageView_cornerRadius, 0);
    a.recycle();
}

public void setCornerRadius(int radius)
{
    this.cornerRadius = radius;
}

@Override
protected void onDraw(Canvas canvas)
{
    boolean applyCornerToBitmap = false;

    Drawable drawable = getDrawable();
    if (drawable != null)
    {
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        if (bitmap != null)
        {
            int viewWidth = getWidth();
            if (viewWidth != 0f)
            { // Only round the corner if view width is not zero.
                // Calculate the corner radius on the real bitmap, based on
                // the
                // corner radius of the view.
                int bitmapWidth = bitmap.getWidth();
                float newBitmapCornerRadius = cornerRadius * bitmapWidth / viewWidth;

                // If newBitmapCornerRadius equals to bitmapCornerRadius,
                // then it is not needed to set the round the corner bitmap
                // to the drawable again.
                if (bitmapCornerRadius != newBitmapCornerRadius)
                {
                    applyCornerToBitmap = true;
                    // Create bitmap with rounded corner.
                    int bitmapHeight = bitmap.getHeight();
                    bitmapCornerRadius = newBitmapCornerRadius;
                    bitmap = Utils.getRoundedCornerBitmap(bitmap, 50);
                    // Set rounded corner bitmap to the view's drawable.
                    setImageBitmap(bitmap); // This will call onDraw()
                                            // again.
                }
            }
        }
    }
    // Call super onDraw() if the drawable has already been rounded.
    if (!applyCornerToBitmap)
    {
        super.onDraw(canvas);
    }
}

}

1 个答案:

答案 0 :(得分:2)

像这样修改,你猜对了,问题与视图回收有关,并且在每个getView方法中,所有图像都必须清除,例如设置占位符或设置为null,我不完全知道imgVw或holder.imageOfDoctor_select必须重置,尝试两者

  

如何在不重新加载imageView中的不同图像的情况下更正并显示正确的图像。

你不能,因为ImageView仍然保留以前的图像

@Override
public View getView(int position, View convertView, ViewGroup arg2) {
    ViewHolder holder = null;

    if (convertView == null) {
        LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = vi.inflate(R.layout.row_health, arg2, false);
        holder = new ViewHolder();
        convertView.setTag(holder);

    }
    else {
        holder = (ViewHolder) convertView.getTag();
    }
    holder.imageOfDoctor_select.setImageBitmap(null); //Or put placeholder here, until image loaded
    loadImage("imageViewURL", relLyt_txtPicInitials, imgVw);
}

我可以提出另一种解决方案,没有目标,只需使用public void into(android.widget.ImageView target, com.squareup.picasso.Callback callback)此类重载类似

Picasso.with(getContext())
            .load(imgVw)
            .into(imgVw, new Callback() {
                @Override
                public void onSuccess() {
                    imgVw.setVisibility(View.VISIBLE);
                    relLyt_txtPicInitials.setVisibility(View.GONE);
                }

                @Override
                public void onError() {

                }
            });