带有来自网络的不同高度的图像的ListView导致“闪烁”

时间:2013-12-12 16:06:07

标签: android performance listview

这是场景:我在ListView上显示了一些信息。每行可以有,标题,正文,日期,头像和更多数据。还有一个来自网络的ImageView。 ImageView在每一行都有不同的高度。我知道下载后px的高度是多少。

我现在正在做的是调整图像的宽度以填充它的父级,并自动自动调整它的高度。

我正在下载图片时加载固定的占位符。

以下是ImageView的代码:

public class ResizableImageView2 extends ImageView {

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
    Drawable d = getDrawable();

    if(d!=null){
        // ceil not round - avoid thin vertical gaps along the left/right edges
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
        setMeasuredDimension(width, height);
    }else{
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}
}

问题是:占位符加载了固定大小,一旦下载我们放置ImageView,布局重新计算它自己,这会导致浪费cpu,慢速滚动。

我已经预先缓存了传入的行,以“最小化”此问题。这样,应用程序在80%的时间内从磁盘/内存加载图像(如果您处于良好的网络中并以正常速度滚动)并且列表视图不会“闪烁”。

我正在搜索的解决方案是将占位符的大小预设为与下载的图像相同的大小。但出于某种原因,我很难做到这一点。

如果需要的话,我可以对图像进行一些裁剪(一些小像素),但是没有任何东西可以使所有图像都以相同的尺寸折断:P

想法?实例

1 个答案:

答案 0 :(得分:1)

最后对我来说解决方案是:

public class ResizableImageView2 extends ImageView {

private int fixedHeight = -1;
private int fixedWidth = -1;

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (BuildConfig.DEBUG) Log.e("ResizableImageView2", "onMeasure called!");

    if (fixedHeight != -1 && fixedWidth != -1) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = (int) Math.ceil((float) width * (float) fixedHeight / (float) fixedWidth);
        setMeasuredDimension(width, height);
    } else {
        Drawable d = getDrawable();
        if (d != null) {
            // ceil not round - avoid thin vertical gaps along the left/right edges
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
            setMeasuredDimension(width, height);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}

public void setFixedHeight(int fixedHeight) {
    this.fixedHeight = fixedHeight;
}

public void setFixedWidth(int fixedWidth) {
    this.fixedWidth = fixedWidth;
}

我可以在使用setFixedHeight和setFixedWidth下载位图之前设置高度和宽度。占位符应为​​9贴片,以便更好地拉伸。在布局中我是android:scaleType =" fitXY"。

有了这个,我可以在下载之前预先设置imageview的大小,一旦下载,图像视图将填充宽度并具有正确宽高比的高度。