最近用的了PullToRefreshListView框架,也在listView中加载图片,对于滑动加载可见item,网上找了一些相关文档,但都不太合适,如:http://blog.csdn.net/zhouzme/article/details/19298337?utm_source=tuicool&utm_medium=referral 不过,大体思路总算清晰了,也就是对于listView做滑动事件监听,关键获取到当前可见item的index序号,从first->last,如有不对的,请大家指导下:
关键代码如下:
1 listView.setOnScrollListener(new OnScrollListener() { 2 3 @Override 4 public void onScrollStateChanged(AbsListView view, int scrollState) { 5 // TODO Auto-generated method stub 6 switch (scrollState) { 7 case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: 8 // Log.i("fm3", "OnScrollListener : SCROLL_STATE_TOUCH_SCROLL"); 9 adapter.setIsScrolling(true); 10 break; 11 case AbsListView.OnScrollListener.SCROLL_STATE_FLING: 12 // Log.i("fm3", "OnScrollListener : SCROLL_STATE_FLING"); 13 adapter.setIsScrolling(true); 14 case AbsListView.OnScrollListener.SCROLL_STATE_IDLE: 15 //第一个可见item的position 16 int first = listView.getRefreshableView().getFirstVisiblePosition(); 17 //最后一个可见item的position 18 int last = listView.getRefreshableView().getLastVisiblePosition(); 19 //屏幕可见item的总数 20 int onScreenCount = listView.getRefreshableView().getChildCount(); 21 adapter.setIsScrolling(false); 22 adapter.setPositionRange(first, last,onScreenCount); 23 adapter.notifyDataSetChanged(); 24 break; 25 default: 26 break; 27 } 28 } 29 30 @Override 31 public void onScroll(AbsListView view, int firstVisibleItem, 32 int visibleItemCount, int totalItemCount) { 33 // TODO Auto-generated method stub 34 } 35 });
adapter代码如下:
1 private boolean isScrolling = false; 2 private int mFirstPosition = 0; 3 private int mLastPosition = 0; 4 private int onScreenCount = 0; //屏幕每次可见item个数 5 private List<Integer> listPosition = new ArrayList<Integer>(); 6 public void setIsScrolling(boolean flag) { 7 this.isScrolling = flag; 8 } 9 /** 10 * 设置滑动到item记录 11 * @param first 12 * @param last 13 * @param onScreenCount 14 */ 15 public void setPositionRange(int first,int last,int onScreenCount) { 16 this.mFirstPosition = first; 17 this.mLastPosition = last; 18 this.onScreenCount = onScreenCount; 19 for(int i=0;i<= onScreenCount;i++) { 20 int currentIndex = first + i; //从第一个可见的item--》最后可见的item 21 if(currentIndex > last) { 22 return; 23 }else { //对于滑动到的item进行记录 24 if(!listPosition.contains(currentIndex)) { 25 listPosition.add(currentIndex); 26 Log.i("fm3","添加可见item记录:"+currentIndex); 27 } 28 } 29 } 30 }
然后还有关键的getView方法:
1 //初始化时自动加载 2 if(this.mLastPosition == 0 || listPosition.contains(position)) { 3 this.setVisableImg(position, data, holder.imgIco); 4 }
也就是关键维护一个记录可见item的ArrayList,如果出现过了,那么滑动到该item才加载。
而对于图片请求网络部分,使用最常用的universal-image-loader框架,可以结合本地缓存、内存缓存,提供图片加载的效率。
还有要注意的一点,快速滑动的时候,如一下子从第一张图片滑动到第七张图片,可能第一张图片还没加载出来,这时候第七张图片已经加载出来了,但是还是因为convertView缓存的原因,会先加载第七张图片,再加载第一张,从而导致图片错位了。
改善办法应该是给ImageView设置Tag:
1 public void setVisableImg(int position, List<DiscoverModel> data, 2 ImageView imageView) { 3 String ico = ConfigureUtils.pic_url + data.get(position).getIco_url(); 4 imageView.setTag(ico); 5 6 //这句话为了解决convertView被重用时,图片预设问题 7 imageView.setImageResource(R.drawable.img_cityhunter_review); 8 if(imageView.getTag().equals(ico)) { 9 // SetImageUtils.setImageRound(ico, context.getResources().getDrawable(R.drawable.img_cityhunter_review), imageView, context); 10 SetImageUtils.setImage(ico, imageView, context); 11 } 12 }