关于getView中图片重复加载
2016-05-31 20:51
387 查看
在ListView或GridView中,经常会出现getView反复调用的问题。究其原因,是视图进行绘制前多次onMeasure的结果。
要解决这个问题,就要避免父视图反复测量以适应整个布局,尽量避免使用wrap_content属性。
普通的getView反复调用问题并不会有太大的影响,会产生影响的往往是在getView中实行的操作,比如在getView中加载图片之类的。
例如,我要在ScrollView中嵌入一个GridView中,然后在GridView显示图片,为了避免一些奇怪的问题产生(比如滑动冲突或者干脆没法滑动),就要覆写onMeasure方法使其自适应:
我将AlbumGridView放入ScrollView中,然后用AlbumGridView加载图片,得到以下Log:
可以看到,getView在重复调用,且第一张图片img (4).jpg更是反复调用了11次。总共4张图片,调用了14次,试验多次,第一张图片总是会反复调用多次——单纯调用getView影响并不大,但因为是图片加载,要在getView中根据uri加载图片,这样问题就大了。
于是改写AlbumGridView并在getView中判断是否在测量中,如果在测量中,就先不加载图片,否则就开始加载图片,这样一来会节省很多资源:
加一个isOnMeasure标记以判断视图当前状态;
这样一来,getView其实还是反复在调用,但是图片加载却不会再反复加载了。其Log如下:
要解决这个问题,就要避免父视图反复测量以适应整个布局,尽量避免使用wrap_content属性。
普通的getView反复调用问题并不会有太大的影响,会产生影响的往往是在getView中实行的操作,比如在getView中加载图片之类的。
例如,我要在ScrollView中嵌入一个GridView中,然后在GridView显示图片,为了避免一些奇怪的问题产生(比如滑动冲突或者干脆没法滑动),就要覆写onMeasure方法使其自适应:
public class AlbumGridView extends GridView { public AlbumGridView(Context context) { super(context); } public AlbumGridView(Context context, AttributeSet attrs) { super(context, attrs); } public AlbumGridView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height =MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, height); } }
我将AlbumGridView放入ScrollView中,然后用AlbumGridView加载图片,得到以下Log:
05-31 08:21:56.729 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (4).jpg 05-31 08:21:56.729 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (4).jpg 05-31 08:21:56.730 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (4).jpg 05-31 08:21:56.730 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (3).jpg 05-31 08:21:56.731 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (2).jpg 05-31 08:21:56.734 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (1).jpg 05-31 08:21:56.800 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (4).jpg 05-31 08:21:56.800 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (4).jpg 05-31 08:21:56.817 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (4).jpg 05-31 08:21:56.817 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (4).jpg 05-31 08:21:56.850 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (4).jpg 05-31 08:21:56.851 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (4).jpg 05-31 08:21:56.878 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (4).jpg 05-31 08:21:56.879 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (4).jpg
可以看到,getView在重复调用,且第一张图片img (4).jpg更是反复调用了11次。总共4张图片,调用了14次,试验多次,第一张图片总是会反复调用多次——单纯调用getView影响并不大,但因为是图片加载,要在getView中根据uri加载图片,这样问题就大了。
于是改写AlbumGridView并在getView中判断是否在测量中,如果在测量中,就先不加载图片,否则就开始加载图片,这样一来会节省很多资源:
public class AlbumGridView extends GridView { public boolean isOnMeasure; public AlbumGridView(Context context) { super(context); } public AlbumGridView(Context context, AttributeSet attrs) { super(context, attrs); } public AlbumGridView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { isOnMeasure = true; int height = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, height); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { isOnMeasure = false; super.onLayout(changed, l, t, r, b); } public boolean isOnMeasure() { return isOnMeasure; }
加一个isOnMeasure标记以判断视图当前状态;
public class PhotosAdapter extends BaseAdapter { ...... @Override public View getView(int position, View convertView, ViewGroup parent) { View view; if (convertView == null) { view = layoutInflater.inflate(R.layout.item, parent, false);//inflate item } else { view = convertView; } if (parent instanceof AlbumGridView) { if (((AlbumGridView) parent).isOnMeasure()) { return view; } else { Log.w("load",""+url); //加载图片 } } return view; } }
这样一来,getView其实还是反复在调用,但是图片加载却不会再反复加载了。其Log如下:
05-31 08:40:54.750 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (4).jpg 05-31 08:40:54.751 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (3).jpg 05-31 08:40:54.751 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (2).jpg 05-31 08:40:54.752 1689-1689/com.xter.picbrowser W/load: file:///storage/emulated/0/Download/img/img (1).jpg
相关文章推荐
- Android开发中ImageLoder进行图片加载和缓存
- ScrollView滚动条颜色的设置方法
- jQuery实现图片加载完成后改变图片大小的方法
- jQuery实现图片预加载效果
- 刷新Activity中的scrollview示例(局部ui刷新)
- js实现图片加载时候逐渐出现的杂色效果
- 关于图片的预加载过程中隐藏未知的
- Android之ScrollView嵌套ListView和GridView冲突的解决方法
- Android实现两个ScrollView互相联动的同步滚动效果代码
- Android图片加载缓存框架Glide
- Android图片加载的缓存类
- Android App中实现图片异步加载的实例分享
- Android开发之机顶盒上gridview和ScrollView的使用详解
- Android控件之ScrollView用法实例分析
- android 实现ScrollView自动滚动的实例代码
- Android ScrollView只能添加一个子控件问题解决方法
- Android编程开发之ScrollView嵌套GridView的方法
- Android中实现监听ScrollView滑动事件
- Android ScrollView使用代码示例
- js判断图片加载完成后获取图片实际宽高的方法