Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發之ListView實現Item局部刷新

Android開發之ListView實現Item局部刷新

編輯:關於Android編程

對於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;
  }
 }

以上內容是關於Android開發之ListView實現Item局部刷新的全部內容,希望對大家有用,更多有關listview局部刷新問題,請登錄本站官網查詢,謝謝!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved