ListView部分更新

# ListView 部分刷新 #

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

[google]:http://google.com/

最近的项目中正好用到了带按钮、进度条的自定义样式的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的按钮跟进度条,从而实现了部分更新。
posted @ 2014-09-25 15:19  陌生旅客  阅读(283)  评论(0)    收藏  举报