Android奇巧:ListView实现Item局部刷新

但是博主在做公司项目的时候,有个下载模块,因为可能同时下载好几个数据,所以用的listview展示所有正在下载的内容。因为下载进度要实时更新,所以要不停的调用notifyDateSetChanged刷新数据。这样会不停的重新绘制整个listview的界面,性能开销非常大。

作者: 来源:博客园| 2015-10-22 10:59
 移动端

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

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

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

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

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

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值