您的位置:首页 > 移动开发 > Android开发

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

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

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



51CTO技术博客



51CTO微站服务号



51CTO学院客户端

 收藏

  分享

对于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{ 

3 private List<AppContent> mDates = null; 
4 private Context mContext; 

6 public AppContentAdapter(Context context) { 
7 this.mContext = context; 
8 } 

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 } 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: