关于android ListView的默认选择操作

在android开发中,ListView应该说是最常用的组件之一。这篇文章不对它的基本应用做讲解,需要了解相关内容的同行,敬请自行问度娘。

实际中,ListView初始化后,要进行一些默认操作,比如,我有个布局是显示部门与下属人员,要求加载完部门列表后,在右边显示第一个部门的下属人员,同时标识当前选中部门(红色符号)。(如下图)

技术分享


从度娘可以看出来,有这个类似需求的同行在不少数,但是,要么是把解决办法笼统地带过,要么是很复杂的分析和解决方法。

对于大部分人来说,其实直接给出解决办法,是更好的答案。下面,我就把我的解决办法分享一下,如果有更好的,希望大家也能分享给我。

我在android方面也是新手,如有不当的地方,还大家望指教。


--------------------------------------------------------------

1.新建一个adapter,目的是重写getView方法(这个是关键)。

public class DefaultSelectedAdapter extends SimpleAdapter {
	private DefalutSelectedHandler handler = null;//定义一个默认选中的处理接口

	public DefaultSelectedAdapter(Context context,
			List<? extends Map<String, ?>> data, int resource, String[] from,
			int[] to, DefalutSelectedHandler toSelect) {
		super(context, data, resource, from, to);
		this.handler = toSelect;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		View view = super.getView(position, convertView, parent);
		//在返回view之前,调用选中处理接口方法;这里不对position==0进行判定,是为了适应更多的,如默认选中最后一个等
		handler.doSelected(position, view, parent);
		return view;
	}

	public interface DefalutSelectedHandler{
		void doSelected(int position, View view, ViewGroup parent);//在这个方法中定义需要的默认操作
	}
}

2.在ListView的生成如下:

final ListView listOrg = (ListView) viewSelect.findViewById(R.id.listOrg);//部门列表
final int listSize = listOrgData.size();//部门列表数据
DefaultSelectedAdapter adapter = new DefaultSelectedAdapter(context_, listOrgData,
		R.layout.org_list_item,
		new String[] { "relateName", "relateId"},
		new int[] { R.id.relateName, R.id.relateId},
		new DefaultSelectedAdapter.DefalutSelectedHandler() {//默认选中的处理接口的实现
			boolean initFlag = false;//用于标识处理接口是否已经成功执行过一次
			@Override
			public void doSelected(int position, View view, ViewGroup parent) {
				if(position==0 && !initFlag){//判断是否是第一项,并且处理接口未完成过
					view.findViewById(R.id.itemIcon).setVisibility(View.VISIBLE);//设定该项前面的符号可见,表示当前选中。
					if(parent!=null){
						int size_ = ((ListView)parent).getChildCount();
						//检查当前列表的个数,与数据的个数是否相等,即ListView已经初步加载完成
						if(size_>0 && listSize==size_){//至此,可以判定该处理接口已经成功执行过一次
							initFlag = true;
						}
					}
				}
			}
		});

listOrg.setAdapter(adapter);
listOrg.setOnItemClickListener(new ListView.OnItemClickListener() {
	boolean firstClick = true;//标识第一次点击
	@Override
	public void onItemClick(AdapterView<?> adapterView, View item, final int position, long row) {
		if(position!=0 && firstClick){//第一次点击时,由于之前没有设定ListView的tag,所以这里强制隐藏第一项的选中符号
			firstClick = false;
			listOrg.getChildAt(0).findViewById(R.id.itemIcon).setVisibility(View.GONE);
		}
		Object tag = adapterView.getTag();
		if(tag!=null){
			View item0 = (View) tag;
			item0.findViewById(R.id.itemIcon).setVisibility(View.GONE);//取消当前项的选择状态
		}
		
		/*
		*下面的performItemClick方法并未能使得这句话生效。
		*从开发中debug信息来看,我个人觉得,应该是这句的执行被ListView的getView方法覆盖了(getView会被多次调用)
		*/
		item.findViewById(R.id.itemIcon).setVisibility(View.VISIBLE);

		adapterView.setTag(item);//设定该ListView的tag,便于点击其它项时,取消当前项的选择状态
		//下面是我的业务处理
		String relateId = ((TextView) item.findViewById(R.id.relateId)).getText().toString();
		String relateName = ((TextView) item.findViewById(R.id.relateName)).getText().toString();
		HashMap<String, String> map = new HashMap<String, String>();
		map.put("relateName", relateName);
		map.put("relateId", relateId);
		renderUserList(viewSelect, map);
	}
});

AlertDialog.Builder builder = new AlertDialog.Builder(context_);
final AlertDialog dialogSelect = builder.setCancelable(true)
		.setView(viewSelect).setTitle("请选择接收人员").create();

dialogSelect.show();
if(curOrg!=null){
	//模拟点击第一项,用于加载数据
	listOrg.performItemClick(
			adapter.getView(0, null, null),
			0, adapter.getItemId(0));
}

上面两步,就是实现这个功能的全部代码。

其核心就是,在getView中调用你的默认选中项的处理方法,只是加入了比较多的判定,防止列表有变化时反复调用getView导致doSelected也被反复执行。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。