ListView部分更新

ListView 部分刷新

我们在Android应用开发中经常会用到ListView这个组件,关于它的特性以及如何优化,网上已经有了太多例子,我就不再赘述,不了解的可以去Google一下。

最近的项目中正好用到了带按钮、进度条的自定义样式的ListView,下面我就来讲一讲ListView中的部分刷新的方法。


适用情景

当ListView的item中出现需要更新状态的部件(比如Button、进度条等),已按钮的状态为例子,当点击这个按钮时,需要根据服务器端返回的状态码对这个按钮的状态的进行变化(如按钮文字的变化),这时如果采用一般的 notifyDataSetChanged() 方法的话,会更新整个ListView,造成ListView界面的闪烁,这会造成很不好的用户体验,所以为了能及时更新按钮的状态,又不造成界面的闪烁,我们就要用到了部分刷新。


相关代码

  • ViewHolder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

static class ViewHolder {

TextView title;
ImageView icon;
ProgressView progressView;
TextView remainder;
TextView content;
Button button;
RelativeLayout container;
String mTagValue = null;

public void setMyTag(String tag) {
mTagValue = tag;
}

public String getMyTag() {
return mTagValue == null ? "" : mTagValue;
}
}

ViewHolder的变化主要是增加了两个方法:setMyTag(String tag) , getMyTag().

这两个方法主要是为了在加载的时候给这个item设置一个标签,并在以后需要刷新的时候找到这个标签,这一块的具体实现在第三部分里有体现。

  • getView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

@Override
public View getView(int position, View view, ViewGroup parent) {
final PresentInfo info = mPresentInfos.get(position);
ViewHolder holder = new ViewHolder();

if (view == null) {
view = mInflater.inflate(R.layout.listview_present_total_list_item, null);
holder = initViewHolder(view);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
setViewHolderDatas(holder, info);
return view;
}

这个方法没什么好说的,用了常规的ListView的优化方式。

  • setViewHolderDatas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

private void setViewHolderDatas(final ViewHolder holder,
final PresentInfo info)
{

if (holder.getMyTag().equals(info.id)) {
// 采用部分更新策略
setPresentButton(holder.button, info.status);
holder.progressView.setBackgroud(ProgressView.DOWNLODEING_BACKGROUD);
holder.progressView.setProgress(info.int_progress);
holder.remainder.setText(mContext.getResources().getString(R.string.game_present_remainder, String.valueOf(info.int_progress) + "%"));
holder.setMyTag(info.id);
return;
}

setUIDatas(holder, info);

holder.setMyTag(info.id);

}

重点在这个方法,第一次加载的时候,所有的ViewHolder都没有被设置标签,所以初始化的时候是调用setUIDatas()方法,这个方法主要是用来设置UI的数据以及状态,我就不详细描述了。

等到后台返回按钮的状态,并且Activity调用notifyDataSetChanged()之后,当ListView重新调用getView()方法时,这个时候的所有ViewHolder都已经有了自己的tag了,这个时候就会根据变化的info信息,如果此item的tag与变化的一致,就只更新此holder的按钮跟进度条,从而实现了部分更新。