欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发之ListView实现Item局部刷新

程序员文章站 2023-12-06 08:54:58
对于android中的listview刷新机制,大多数的程序员都是很熟悉的,修改或者添加adapter中的数据源之后,然后调用notifydatasetchanged()刷...

对于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局部刷新问题,请登录官网查询,谢谢!