对于ListView数据的刷新大家都知道,改变Adapter的数据源,然后调用Adapter的notifyDateSetChanged()方法即可。通过本篇文章给大家详细介绍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;          


                      }          


           }