zoukankan      html  css  js  c++  java
  • 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实现多任务多线程下载》的例子中的,如果需要可以去下载。

     

  • 相关阅读:
    常见的排序算法(四):归并排序
    常见的排序算法(三):快速排序
    常见的排序算法(二):选择排序
    a标签没有闭合引起自动插入很多a标签的问题
    js笔记
    Vue笔记
    CSS笔记
    bootstrap--网格化布局
    backgroud图片充满元素的方法
    bootstrap--概述
  • 原文地址:https://www.cnblogs.com/liuling/p/2015-10-20-01.html
Copyright © 2011-2022 走看看