我们在Android应用开发中经常会用到ListView这个组件,关于它的特性以及如何优化,网上已经有了太多例子,我就不再赘述,不了解的可以去Google一下。
最近的项目中正好用到了带按钮、进度条的自定义样式的ListView,下面我就来讲一讲ListView中的部分刷新的方法。
适用情景
当ListView的item中出现需要更新状态的部件(比如Button、进度条等),已按钮的状态为例子,当点击这个按钮时,需要根据服务器端返回的状态码对这个按钮的状态的进行变化(如按钮文字的变化),这时如果采用一般的 notifyDataSetChanged()
方法的话,会更新整个ListView,造成ListView界面的闪烁,这会造成很不好的用户体验,所以为了能及时更新按钮的状态,又不造成界面的闪烁,我们就要用到了部分刷新。
相关代码
- ViewHolder
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
@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
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的按钮跟进度条,从而实现了部分更新。