当listivew包含的几十条data,item包含progressbar,默认显示下载图片,点击progressbar要开始下载,同时用progressbar刷新进度。
ListView只会缓存第一屏里面的List Item的视图布局,之后滚动ListView后面的Item的布局就都是用前面所缓存的视图布局(也就是convertView不为null)。这样如果当后面的某一条记录里面的某些控件因上面的原因没有赋值,就会直接使用前面所缓存的视图里面的值了(里面有值的话)。
这样的最终效果就是,滚动的时候,会出现前面已经出现过的内容。
最简单的解决方法就是,在上面的代码中不去判断赋值内容是否为空,而是直接设定对应该控件的值,即使用事例代码中的注释部分。(去掉上面代码中的if段)
真正的解决方法,则规避不对ViewHolder中的元素进行赋值这种情况。
if(list.get(position).getmInfo()!=null){
holder.itemStatus.setMax((int) list.get(position).getmInfo().getFileLength());
holder.itemStatus.setProgress((int)list.get(position).getmInfo().getProgress());
}else{
holder.itemStatus.setProgress(0);//这里不要省略
}
如果这里不为progressbar设置没有数据时的默认值,那么滑动时会发生progressbar的data错位问题。
刷新progress不要使用notifydatasetchanged,
发现它针对每一个子View都做了刷新,当然,如果我们的数据都变量还可以理解。但是,一般条件下,我们需要更新的View不多。频繁的调用NotifyDataSetChanged方法,刷新整个界面不合适。这样会把界面上显示的所有item都全部重绘一次,即使只有一个view的内容发生了变化。
所以,我们可以写一个update的方法,来单独刷新一个View
int firstVisiblePosition = MyHomeActivity.listView.getFirstVisiblePosition();
int lastVisiblePosition = MyHomeActivity.listView.getLastVisiblePosition();
if(position>=firstVisiblePosition && position<=lastVisiblePosition){
View view = MyHomeActivity.listView.getChildAt(position - firstVisiblePosition);
if(view.getTag() instanceof ViewHolder){
ViewHolder vh = (ViewHolder)view.getTag();
LogUtil.printLog("局部更新:", progress+" position="+position);
vh.itemStatus.setProgress(progress);
}
}