三嫁皇妃,娇妻李甜,绝世舞男
对于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局部刷新问题,请登录移动技术网官网查询,谢谢!
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Android studio开发小型对话机器人app(实例代码)
Android通过Java sdk的方式接入OpenCv的方法
Android 通过cmake的方式接入opencv的方法步骤
Android Studio finish()方法的使用与解决app点击“返回”(直接退出)
Android 进度条 ProgressBar的实现代码(隐藏、出现、加载进度)
网友评论