ListView实现Item局部刷新

   对于ListView数据的刷新大家都知道,改变Adapter的数据源,然后调用Adapter的notifyDateSetChanged()方法即可。

  但是博主在做公司项目的时候,有个下载模块,因为可能同时下载好几个数据,所以用的listview展示所有正在下载的内容。因为下载进度要实时更新,所以要不停的调用notifyDateSetChanged刷新数据。这样会不停的重新绘制整个listview的界面,性能开销非常大。而且如果每个item有图片的话,每个item的图片都需要重新加载,就算图片做了内存缓存,刷新一下图片也会闪一下,不停的刷新就会导致各个item的图片不停的闪,体验一点都不好。

  那么对于上面问题,有没有解决办法呢?当然是有的。我们可以针对某一个item进行局部更新,而不影响其它没有修改的item。那么具体如何实现的呢?我们看下面的代码。

 1     private void updateView(int itemIndex) {
 2         //得到第一个可显示控件的位置,
 3         int visiblePosition = mListView.getFirstVisiblePosition();
 4         //只有当要更新的view在可见的位置时才更新,不可见时,跳过不更新
 5         if (itemIndex - visiblePosition >= 0) {
 6             //得到要更新的item的view
 7             View view = mListView.getChildAt(itemIndex - visiblePosition);
 8             //调用adapter更新界面
 9             mAdapter.updateView(view, itemIndex);
10         }
11     }

  这个函数主要是根据传入的itemIndex来获取第itemIndex的数据所显示的view。itemIndex就是要修改的数据再List集合中的位置,比如我这里下载进度有更新,发了一个广播这里接收到了,需要修改该下载内容的进度条,广播接收器可以这么写:

 1         @Override
 2         public void onReceive(Context context, Intent intent) {
 3             AppContent appContent = intent.getParcelableExtra("appContent");
 4             if(appContent == null) return;
 5             int itemIndex = 0;
 6             for(AppContent appContent1 : mList) {
 7                 if(appContent.getUrl().equals(appContent1.getUrl())) {
 8                     itemIndex = mList.indexOf(appContent1);
 9                     appContent1.setDownloadPercent(appContent.getDownloadPercent());
10                     break;
11                 }
12             }
13             updateView(itemIndex);
14         }

  下面看Adapter的具体代码:

  1 public class AppContentAdapter extends BaseAdapter{
  2
  3     private List<AppContent> mDates = null;
  4     private Context mContext;
  5
  6     public AppContentAdapter(Context context) {
  7         this.mContext = context;
  8     }
  9
 10     @Override
 11     public int getCount() {
 12         return mDates.size();
 13     }
 14
 15     @Override
 16     public Object getItem(int position) {
 17         return mDates.get(position);
 18     }
 19
 20     @Override
 21     public long getItemId(int position) {
 22         return position;
 23     }
 24
 25     public void setDates(List<AppContent> mDates) {
 26         this.mDates = mDates;
 27     }
 28
 29     @Override
 30     public View getView(int position, View convertView, ViewGroup parent) {
 31         ViewHolder holder = null;
 32         if (convertView == null) {
 33             holder = new ViewHolder();
 34             convertView = LayoutInflater.from(mContext).inflate(
 35                     R.layout.listitem_download, null);
 36             holder.statusIcon = (DownloadPercentView) convertView.findViewById(R.id.status_icon);
 37             holder.name = (TextView) convertView.findViewById(R.id.name);
 38             holder.downloadPercent = (TextView) convertView.findViewById(R.id.download_percent);
 39             holder.progressBar = (ProgressBar) convertView.findViewById(R.id.progressbar);
 40             convertView.setTag(holder);
 41         } else {
 42             holder = (ViewHolder) convertView.getTag();
 43         }
 44         setData(holder, position);
 45         return convertView;
 46     }
 47
 48     /**
 49      * 设置viewHolder的数据
 50      * @param holder
 51      * @param itemIndex
 52      */
 53     private void setData(ViewHolder holder, int itemIndex) {
 54         AppContent appContent = mDates.get(itemIndex);
 55         holder.name.setText(appContent.getName());
 56         holder.progressBar.setProgress(appContent.getDownloadPercent());
 57         setIconByStatus(holder.statusIcon, appContent.getStatus());
 58         if(appContent.getStatus() == AppContent.Status.PENDING) {
 59             holder.downloadPercent.setVisibility(View.INVISIBLE);
 60         } else {
 61             holder.downloadPercent.setVisibility(View.VISIBLE);
 62             holder.statusIcon.setProgress(appContent.getDownloadPercent());
 63             holder.downloadPercent.setText("下载进度:" + appContent.getDownloadPercent() + "%");
 64         }
 65     }
 66
 67
 68     /**
 69      * 局部刷新
 70      * @param view
 71      * @param itemIndex
 72      */
 73     public void updateView(View view, int itemIndex) {
 74         if(view == null) {
 75             return;
 76         }
 77         //从view中取得holder
 78         ViewHolder holder = (ViewHolder) view.getTag();
 79         holder.statusIcon = (DownloadPercentView) view.findViewById(R.id.status_icon);
 80         holder.name = (TextView) view.findViewById(R.id.name);
 81         holder.downloadPercent = (TextView) view.findViewById(R.id.download_percent);
 82         holder.progressBar = (ProgressBar) view.findViewById(R.id.progressbar);
 83         setData(holder, itemIndex);
 84     }
 85
 86     /**
 87      * 根据状态设置图标
 88      * @param downloadPercentView
 89      * @param status
 90      */
 91     private void setIconByStatus(DownloadPercentView downloadPercentView, AppContent.Status status) {
 92         downloadPercentView.setVisibility(View.VISIBLE);
 93         if(status == AppContent.Status.PENDING) {
 94             downloadPercentView.setStatus(DownloadPercentView.STATUS_PEDDING);
 95         }
 96         if(status == AppContent.Status.DOWNLOADING) {
 97             downloadPercentView.setStatus(DownloadPercentView.STATUS_DOWNLOADING);
 98         }
 99         if(status == AppContent.Status.WAITING) {
100             downloadPercentView.setStatus(DownloadPercentView.STATUS_WAITING);
101         }
102         if(status == AppContent.Status.PAUSED) {
103             downloadPercentView.setStatus(DownloadPercentView.STATUS_PAUSED);
104         }
105         if(status == AppContent.Status.FINISHED) {
106             downloadPercentView.setStatus(DownloadPercentView.STATUS_FINISHED);
107         }
108     }
109
110     private class ViewHolder {
111         private DownloadPercentView statusIcon;
112         private TextView name;
113         private TextView downloadPercent;
114         private ProgressBar progressBar;
115     }
116 }

  其实这些代码就是我上篇博文《AsyncTask实现多任务多线程下载》的例子中的,如果需要可以去下载。

时间: 2024-12-23 22:13:22

ListView实现Item局部刷新的相关文章

android Listview,gridview局部刷新,部分刷新

众所周知Listview和Gridview的刷新界面的方式是调用adapter.notifyDataSetChanged()进行界面刷新. 但是此方法有其弊端,他是将界面中的数据全部刷新一遍,不论数据有没有变化.如果listview加载了很多的数据(如:100条) 在进行刷新时就会造成很大的系统开销如何像qq空间个人动态那样点赞只刷新一条呢: 主要原理: 对listview的某一个item进行刷新 1.要获取要刷新的item当前索引position和数据 2.对获取的数据进行重置 3.将重置的数

转 android Listview,gridview局部刷新,部分刷新 (仿QQ动态评论局部刷新)

转自:http://blog.csdn.net/jdsjlzx/article/details/45582719 众所周知Listview和Gridview的刷新界面的方式是调用adapter.notifyDataSetChanged()进行界面刷新. 但是此方法有其弊端,他是将界面中的数据全部刷新一遍,不论数据有没有变化.如果listview加载了很多的数据(如:100条) 在进行刷新时就会造成很大的系统开销如何像qq空间个人动态那样点赞只刷新一条呢: 主要原理: 对listview的某一个i

listview,gridview局部刷新,部分刷新

众所周知Listview和Gridview的刷新界面的方式是调用adapter.notifyDataSetChanged()进行界面刷新. 但是此方法有其弊端,他是将界面中的数据全部刷新一遍,不论数据有没有变化.如果listview加载了很多的数据(如:100条) 在进行刷新时就会造成很大的系统开销如何像qq空间个人动态那样点赞只刷新一条呢: 主要原理: 对listview的某一个item进行刷新 1.要获取要刷新的item当前索引position和数据 2.对获取的数据进行重置 3.将重置的数

ListView的局部刷新

有的列表可能notifyDataSetChanged()代价有点高,最好能局部刷新. 局部刷新的重点是,找到要更新的那项的View,然后再根据业务逻辑更新数据即可. private void updateItem(int index) { int visiblePosition = listView.getFirstVisiblePosition(); if (index - visiblePosition >= 0) { //得到要更新的item的view View view = listVi

Android listview局部刷新和模拟应用下载(zhu)

在android开发中,listview是比较常用的一个组件,在listview的数据需要更新的时候,一般会用notifyDataSetChanged()这个函数,但是它会更新listview中所有可视范围内的item,这样对性能肯定会有影响.比较常见的情景是android应用商店中的下载列表,当我们下载一款游戏的时候,只需要更新这款游戏对应的进度就可以了.本文就来模拟android应用商店的游戏下载,实现对listview的局部刷新,只实现一个简单的demo,不去真的下载文件.1. 首先来创建

android:ListView的局部刷新

1.简介 对于android中的ListView刷新机制,大多数的程序员都是很熟悉的,修改或者添加adapter中的数据源之后,然后调用notifyDataSetChanged()刷新ListView.在这种模式下,我们会在getView中,根据不同的数据源,让控件显示不同的内容.这种模式是最常见的刷新模式,当我们来回滑动ListView的时候,调用adapter的getView方法,然后listview对adapter返回的View进行绘制.这种模式下,View的显示内容或状态都记录在adap

listView局部刷新

listview局部刷新关键逻辑代码:在activity中 /** * listview局部更新 */ private void updateListView(int position){ int firstVisiblePosition = mListView.getFirstVisiblePosition(); int lastVisiblePosition = mListView.getLastVisiblePosition(); if(position>=firstVisiblePosi

安卓易学,爬坑不易——腾讯老司机的RecyclerView局部刷新爬坑之路

针对手游的性能优化,腾讯WeTest平台的Cube工具提供了基本所有相关指标的检测,为手游进行最高效和准确的测试服务,不断改善玩家的体验.目前功能还在免费开放中. 点击地址:http://wetest.qq.com/cube立即体验! 作者:Hoolly,腾讯移动客户端开发工程师. 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处 WeTest导读 安卓开发者都知道,RecyclerView比ListView要灵活的多,但不可否认的里面的坑也同样埋了不少人.下面让我们看看腾讯开发工程

android:RecyclerView局部刷新那点事~

1.局部刷新的引入提到RecyclerView,我们首先想到的是ListView,对于ListView的局部刷新,我们之前已经有解决方案,[android:ListView的局部刷新]当时的解决方案是:记录点击的Item的position,然后在更新过程中,不断的判断,该position是不是介于可见的Item之间,如果是,则更新,否者,不更新.2.RecyclerView的局部更新 按照之前的思路,首先要寻找RecyclerView中可见的item的位置范围,该方法并不在RecyclerVie