具有缩略图的ListView不能平滑滚动

时间:2013-12-01 11:53:43

标签: android listview

我有一个包含缩略图的列表视图。我从网址获取缩略图。我正在下载缩略图时显示一个微调器。

问题
在列表视图的开头,几乎同时所有的微调器都被下载的图像替换。旋转器冻结,列表视图冻结0.5秒。

当我以明显的速度滚动浏览列表视图时,同样的情况也会发生。

问题
如何加快我的列表浏览速度,让它再次流畅?我应该在后台执行某些任务,还是逐个下载和设置图像。或者别的什么?

GetView

 public View getView(int position, View convertView, ViewGroup parent) {

    if(convertView == null){

        convertView = mInflater.inflate(R.layout.listview_row, null);
    }

    UrlImageView thumb = (UrlImageView) convertView.findViewById(R.id.thumbnail);

    final Video video = videos.get(position);
    // Set the image for the list item
    thumb.setImageDrawable(video.getThumbUrl());    
    return convertView;
}

我还注意到,如果我使用 if(convertView == null){来回收列表项,有时会显示错误的缩略图。

UrlImageView

package com.package;

import static android.app.Activity.RESULT_CANCELED;
import static android.app.Activity.RESULT_OK;

import imports;

public class UrlImageView extends LinearLayout {

private Context mContext;
private Drawable mDrawable;
private ProgressBar mSpinner;
private ImageView mImage;

public UrlImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

public UrlImageView(Context context) {
    super(context);
    init(context);
}

private void init(final Context context) {
    mContext = context;

    int width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80, getResources().getDisplayMetrics());
    int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics());

    mImage = new ImageView(mContext);
    mImage.setLayoutParams(new LayoutParams(width,height));
    mImage.setScaleType(ScaleType.CENTER_CROP);
    mImage.setVisibility(View.VISIBLE);

    mSpinner = new ProgressBar(mContext);
    mSpinner.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));

    mSpinner.setIndeterminate(true);

    addView(mSpinner);
    addView(mImage);
}

/**
 * Set's the view's drawable, this uses the internet to retrieve the image
 * don't forget to add the correct permissions to your manifest
 * 
 * @param imageUrl the url of the image you wish to load
 */
public void setImageDrawable (final String imageUrl) {
    mDrawable = null;
    mSpinner.setVisibility(View.VISIBLE);
    mImage.setVisibility(View.VISIBLE);
    new Thread() {
        public void run() {
            try {
                mDrawable = getDrawableFromUrl(imageUrl);
                imageLoadedHandler.sendEmptyMessage(RESULT_OK);
            } catch (MalformedURLException e) {
                imageLoadedHandler.sendEmptyMessage(RESULT_CANCELED);
            } catch (IOException e) {
                imageLoadedHandler.sendEmptyMessage(RESULT_CANCELED);
            }
        };
    }.start();
}

/**
 * Callback that is received once the image has been downloaded
 */
private final Handler imageLoadedHandler = new Handler(new Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
        case RESULT_OK:
            mImage.setImageDrawable(mDrawable);
            mImage.setVisibility(View.VISIBLE);

            mSpinner.setVisibility(View.GONE);
            break;
        case RESULT_CANCELED:
        default:
            // possible fail image
            break;
        }
        return true;
    }
});

private static Drawable getDrawableFromUrl (final String url) throws IOException, MalformedURLException {

    return Drawable.createFromStream(((java.io.InputStream) new java.net.URL(url).getContent()), "name");
}

}

1 个答案:

答案 0 :(得分:1)

查看此官方博客文章,了解一些提示:

http://developer.android.com/training/improving-layouts/smooth-scrolling.html