首页 > 系统 > Android > 正文

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

2019-10-24 20:35:16
字体:大 中 小
来源:转载
供稿:网友

对于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。那么具体如何实现的呢?我们看下面的代码。

 

 
  1. private void updateView(int itemIndex) { 
  2. //得到第一个可显示控件的位置, 
  3. int visiblePosition = mListView.getFirstVisiblePosition(); 
  4. //只有当要更新的view在可见的位置时才更新,不可见时,跳过不更新 
  5. if (itemIndex - visiblePosition >= ) { 
  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 = ; 
  6. for(AppContent appContent : mList) { 
  7. if(appContent.getUrl().equals(appContent.getUrl())) { 
  8. itemIndex = mList.indexOf(appContent); 
  9. appContent.setDownloadPercent(appContent.getDownloadPercent()); 
  10. break; 
  11. } 
  12. } 
  13. updateView(itemIndex); 
  14. } 

下面看Adapter的具体代码:

 

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

以上内容是关于Android开发之ListView实现Item局部刷新的全部内容,希望对大家有用,更多有关listview局部刷新问题,请登录武林网官网查询,谢谢!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表