Android开发之ListView实现Item局部刷新
对于android中的listview刷新机制,大多数的程序员都是很熟悉的,修改或者添加adapter中的数据源之后,然后调用notifydatasetchanged()刷新listview。在这种模式下,我们会在getview中,根据不同的数据源,让控件显示不同的内容。这种模式是最常见的刷新模式,当我们来回滑动listview的时候,调用adapter的getview方法,然后listview对adapter返回的view进行绘制。这种模式下,view的显示内容或状态都记录在adapter里面的数据源中,listview的更新频率不频繁,它随着数据源的变化而更新。
但是小编在做公司项目的时候,有个下载模块,因为可能同时下载好几个数据,所以用的listview展示所有正在下载的内容。因为下载进度要实时更新,所以要不停的调用notifydatesetchanged刷新数据。这样会不停的重新绘制整个listview的界面,性能开销非常大。而且如果每个item有图片的话,每个item的图片都需要重新加载,就算图片做了内存缓存,刷新一下图片也会闪一下,不停的刷新就会导致各个item的图片不停的闪,体验一点都不好。
那么对于上面问题,有没有解决办法呢?当然是有的。我们可以针对某一个item进行局部更新,而不影响其它没有修改的item。那么具体如何实现的呢?我们看下面的代码。
private void updateview(int itemindex) { //得到第一个可显示控件的位置, int visibleposition = mlistview.getfirstvisibleposition(); //只有当要更新的view在可见的位置时才更新,不可见时,跳过不更新 if (itemindex - visibleposition >= ) { //得到要更新的item的view view view = mlistview.getchildat(itemindex - visibleposition); //调用adapter更新界面 madapter.updateview(view, itemindex); } }
这个函数主要是根据传入的itemindex来获取第itemindex的数据所显示的view。itemindex就是要修改的数据再list集合中的位置,比如我这里下载进度有更新,发了一个广播这里接收到了,需要修改该下载内容的进度条,广播接收器可以这么写:
@override public void onreceive(context context, intent intent) { appcontent appcontent = intent.getparcelableextra("appcontent"); if(appcontent == null) return; int itemindex = ; for(appcontent appcontent : mlist) { if(appcontent.geturl().equals(appcontent.geturl())) { itemindex = mlist.indexof(appcontent); appcontent.setdownloadpercent(appcontent.getdownloadpercent()); break; } } updateview(itemindex); }
下面看adapter的具体代码:
public class appcontentadapter extends baseadapter{ private list<appcontent> mdates = null; private context mcontext; public appcontentadapter(context context) { this.mcontext = context; } @override public int getcount() { return mdates.size(); } @override public object getitem(int position) { return mdates.get(position); } @override public long getitemid(int position) { return position; } public void setdates(list<appcontent> mdates) { this.mdates = mdates; } @override public view getview(int position, view convertview, viewgroup parent) { viewholder holder = null; if (convertview == null) { holder = new viewholder(); convertview = layoutinflater.from(mcontext).inflate( r.layout.listitem_download, null); holder.statusicon = (downloadpercentview) convertview.findviewbyid(r.id.status_icon); holder.name = (textview) convertview.findviewbyid(r.id.name); holder.downloadpercent = (textview) convertview.findviewbyid(r.id.download_percent); holder.progressbar = (progressbar) convertview.findviewbyid(r.id.progressbar); convertview.settag(holder); } else { holder = (viewholder) convertview.gettag(); } setdata(holder, position); return convertview; } /** * 设置viewholder的数据 * @param holder * @param itemindex */ private void setdata(viewholder holder, int itemindex) { appcontent appcontent = mdates.get(itemindex); holder.name.settext(appcontent.getname()); holder.progressbar.setprogress(appcontent.getdownloadpercent()); seticonbystatus(holder.statusicon, appcontent.getstatus()); if(appcontent.getstatus() == appcontent.status.pending) { holder.downloadpercent.setvisibility(view.invisible); } else { holder.downloadpercent.setvisibility(view.visible); holder.statusicon.setprogress(appcontent.getdownloadpercent()); holder.downloadpercent.settext("下载进度:" + appcontent.getdownloadpercent() + "%"); } } /** * 局部刷新 * @param view * @param itemindex */ public void updateview(view view, int itemindex) { if(view == null) { return; } //从view中取得holder viewholder holder = (viewholder) view.gettag(); holder.statusicon = (downloadpercentview) view.findviewbyid(r.id.status_icon); holder.name = (textview) view.findviewbyid(r.id.name); holder.downloadpercent = (textview) view.findviewbyid(r.id.download_percent); holder.progressbar = (progressbar) view.findviewbyid(r.id.progressbar); setdata(holder, itemindex); } /** * 根据状态设置图标 * @param downloadpercentview * @param status */ private void seticonbystatus(downloadpercentview downloadpercentview, appcontent.status status) { downloadpercentview.setvisibility(view.visible); if(status == appcontent.status.pending) { downloadpercentview.setstatus(downloadpercentview.status_pedding); } if(status == appcontent.status.downloading) { downloadpercentview.setstatus(downloadpercentview.status_downloading); } if(status == appcontent.status.waiting) { downloadpercentview.setstatus(downloadpercentview.status_waiting); } if(status == appcontent.status.paused) { downloadpercentview.setstatus(downloadpercentview.status_paused); } if(status == appcontent.status.finished) { downloadpercentview.setstatus(downloadpercentview.status_finished); } } private class viewholder { private downloadpercentview statusicon; private textview name; private textview downloadpercent; private progressbar progressbar; } }
其实这些代码就是我上篇博文《asynctask实现多任务多线程下载》的例子中的,如果需要可以去下载。
以上内容是关于android开发之listview实现item局部刷新的全部内容,希望对大家有用,更多有关listview局部刷新问题,请登录官网查询,谢谢!
上一篇: 用java实现冒泡排序算法
推荐阅读
-
Android开发笔记之:ListView刷新顺序的问题详解
-
Android开发之ListView实现Item局部刷新
-
Android开发实现ListView点击item改变颜色功能示例
-
android开发教程之实现listview下拉刷新和上拉刷新效果
-
Android开发之ListView列表刷新和加载更多实现方法
-
Android开发之ListView功能扩展,实现高性能的瀑布流布局讲解
-
android开发教程之实现listview下拉刷新和上拉刷新效果
-
Android开发之ListView列表刷新和加载更多实现方法
-
Android开发实现ListView点击item改变颜色功能示例
-
android开发之捕获ListView中每个item点击事件(代码实例)