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