ListView,Expandable 自定义单选,多选功能实现及注意

经常会遇到很多人问,有没有ListView单选多选的实现的Demo之类的问题。因此,再次贴出一些相关代码,和说明注意事项。

首先介绍的是关于ListView(在此布局文件不与贴出,item的布局主要是用CheckBox在显示选择取消,当然你也可以也用其他类似控件)

一、ListView

 1、adapater实现,具体说明看注释

public  void Adapter extends BaseAdapter {
// 填充数据的list 
// private ArrayList<String> list; 
private List<User> list;
// 用来控制CheckBox的选中状况 
private static HashMap<Integer, Boolean> isSelected; 
// 上下文 
private Context context; 
// 用来导入布局 
private LayoutInflater inflater = null; 


// 构造器 
public Adapter(Context context,List<User> list) { 
this.context = context; 
this.list = list; 
inflater = LayoutInflater.from(context); 
isSelected = new HashMap<Integer, Boolean>(); 
// 初始化数据 
initDate(); 
} 

// 初始化isSelected的数据 
private void initDate() { 
for (int i = 0; i < list.size(); i++) { 
getIsSelected().put(i, false); 
} 
} 

@Override 
public int getCount() { 
return list.size()==0?0:list.size(); 
} 

@Override 
public Object getItem(int position) { 
return list.get(position); 
} 

@Override 
public long getItemId(int position) { 
return position; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
ViewHolder holder = null; 
if (convertView == null) { 
// 获得ViewHolder对象 
holder = new ViewHolder(); 
// 导入布局并赋值给convertview 
convertView = inflater.inflate(R.layout., null); 
holder.cb = (CheckBox) convertView.findViewById
// 为view设置标签 
convertView.setTag(holder); 
} else { 
// 取出holder 
holder = (ViewHolder) convertView.getTag(); 
} 
// 设置list中TextView的显示 
// 根据isSelected来设置checkbox的选中状况 
holder.cb.setChecked(getIsSelected().get(position)); 
return convertView; 
} 

public static class ViewHolder { 
TextView tv; 
public CheckBox cb; 
} 
//下面两个方法非常重要,主要用来标记checkbox的位置及check的值
public static HashMap<Integer, Boolean> getIsSelected() { 
return isSelected; 
} 

public static void setIsSelected(HashMap<Integer, Boolean> isSelected) { 
Adapter.isSelected = isSelected; 
	} 

} 
2、OnItemClickListener实现

public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			adapterView = view;
			if (!mode.equals("0")) {
				// 多选
				try {

					User user = new User();
					// 取得ViewHolder对象,这样就省去了通过层层的findViewById去实例化我们需要的cb实例的步骤
					ViewHolder holder = (ViewHolder) view.getTag();
					// 改变CheckBox的状态
					holder.cb.toggle();
					// 将CheckBox的选中状况记录下来
<span style="white-space:pre">					</span>Adapter.getIsSelected().put(position, holder.cb.isChecked());
					// 调整选定条目
					if (holder.cb.isChecked() == true) {
						user.setUserId(dataTestList.get(position).getUserId());
						user.setUserName(dataTestList.get(position).getUserName());
						userList.add(user);
					} else {
						if (userList.size() != -1) {
						int length = userList.size();
						for (int i = 0; i < length; i++) {
						if (dataTestList.get(position).getUserId()
							.equals(userList.get(i).getUserId())) {	
							userList.remove(i);
							length = length - 1;
							dataChanged();//<span style="font-family: Arial, Helvetica, sans-serif;">adapter.notifyDataSetChanged();</span>
								}
							}
						}
					}
				} catch (Exception e) {
					e.getStackTrace();
				}
			} else {
				// 单选
				// 取得ViewHolder对象,这样就省去了通过层层的findViewById去实例化我们需要的cb实例的步骤
				ViewHolder holder = (ViewHolder) view.getTag();
				// 改变CheckBox的状态
				holder.cb.toggle();
				// 遍历所有checkbox 设置为false
				for (int i = 0; i < dataTestList.size(); i++) {
					if (Adapter.getIsSelected().get(i)) {
<span style="white-space:pre">					</span>Adapter.getIsSelected().put(i,false);
					}
				}
				userList.clear();
				// 重新赋值
				Adapter.getIsSelected().put(position,
						holder.cb.isChecked());
				if (holder.cb.isChecked()) {
					User user = new User();
					user.setUserId(dataTestList.get(position).getUserId());
					user.setUserName(dataTestList.get(position).getUserName());
				}
				dataChanged();<span style="font-family: Arial, Helvetica, sans-serif;">//</span><span style="font-family: Arial, Helvetica, sans-serif;">adapter.notifyDataSetChanged();</span>

			}
			//
		}
	};

以上是ListView实现单选多选的主要代码。

二、ExpandableListView 

      ExpandableListView实现单选多选过程中 与listview实现的方式大致一样,只要区别在于记录CheckBox的位置的时候需要特别主要,还有在监听选择时候,需要对数据有一点点的逻辑修改。

1、Adapter的实现(再次只写选择子类,父类选择可以参考listview实现)

public class ExpandableListtAdapter extends BaseExpandableListAdapter {
	private Context mContext;
	private List<ReceiveSubmitNode> receiverList;
	// 用来控制CheckBox的选中状况
	private static HashMap<Integer, Boolean> isSelected;
	private int checkGroup=-1;
	public ExpandableListtAdapter(Context mContext,
			List<ReceiveSubmitNode> receiverList) {
		super();
		this.mContext = mContext;
		this.receiverList = receiverList;
		isSelected = new HashMap<Integer, Boolean>();
		
		for (int i = 0; i < receiverList.size(); i++) {
			for (int j = 0; j < receiverList.get(i).getNodeUserList().size(); j++) {
				 getIsSelected().put(j, false); 
			}
		}
	}


	// 父节点
	@Override
	public int getGroupCount() {
		return receiverList.size();
	}

	@Override
	public Object getGroup(int groupPosition) {
		return receiverList.get(groupPosition);
	}

	@Override
	public long getGroupId(int groupPosition) {
		return groupPosition;
	}

	@Override
	public View getGroupView(int groupPosition, boolean isExpanded,
			View convertView, ViewGroup parent) {
		FatherHander v = new FatherHander();
		if (convertView == null) {
			convertView = LayoutInflater
					.from(mContext)
					.inflate(
							R.layout.,
							null);
			v.nodeName = (TextView) convertView
					.findViewById(R.id.);
			v.iv = (ImageView) convertView
					.findViewById(R.id.);
			convertView.setTag(v);
		} else {
			v = (FatherHander) convertView.getTag();
		}

		if (isExpanded) {
			v.iv.setBackgroundDrawable(mContext.getResources().getDrawable(
					R.drawable.cch2));
		} else {
			v.iv.setBackgroundDrawable(mContext.getResources().getDrawable(
					R.drawable.cch1));
		}
		return convertView;

	}

	// 子节点
	@Override
	public int getChildrenCount(int groupPosition) {
		// 初始化数据 // 初始化isSelected的数据
		int index;
		try {
			index = receiverList.get(groupPosition).getNodeUserList().size() == 0 ? 0
					: receiverList.get(groupPosition).getNodeUserList().size();
		} catch (Exception e) {
			// TODO: handle exception
			index = 0;
		}
		return index;

	}

	@Override
	public Object getChild(int groupPosition, int childPosition) {
		return receiverList.get(groupPosition).getNodeUserList()
				.get(childPosition);
	}

	@Override
	public long getChildId(int groupPosition, int childPosition) {
		return childPosition;
	}

	@Override
	public View getChildView(final int groupPosition, final int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		ChildsHander c = new ChildsHander();
		if (convertView == null) {
			convertView = LayoutInflater.from(mContext).inflate(
					R.layout, null);
			c.checkBox = (CheckBox) convertView
					.findViewById(R.id.);
			convertView.setTag(c);
		} else {
			c = (ChildsHander) convertView.getTag();
		}


		// 根据isSelected来设置checkbox的选中状况
		c.checkBox.setChecked(getIsSelected().get(childPosition));
		c.checkBox.setClickable(false);
		c.checkBox.setEnabled(false);
		notifyDataSetChanged();
		return convertView;
	}

	private List<String> checkedChildren = new ArrayList<String>();//得到子节点数据
	// 其他方法
	@Override
	public boolean hasStableIds() {
		return true;
	}
	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		return true; // 子节点事件 需要的话返回true
	}

	public static HashMap<Integer, Boolean> getIsSelected() {
		return isSelected;
	}

	public static void setIsSelected(HashMap<Integer, Boolean> isSelected) {
		ExpandableListtAdapter.isSelected = isSelected;
	}
	
	public class FatherHander {
		TextView nodeName;
		public ImageView iv;
	}

	public class ChildsHander {
		TextView userName;
		public CheckBox checkBox;
	}

}

2.实现 setOnChildClickListener

.setOnChildClickListener(new OnChildClickListener() {
			@Override
			public boolean onChildClick(ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {

				if (mode.equals("0")) {
					System.out.println("单选");
					// //单选
					// 取得ViewHolder对象,这样就省去了通过层层的findViewById去实例化我们需要的cb实例的步骤
					ChildsHander holder = (ChildsHander) v.getTag();
					// 改变CheckBox的状态
					holder.checkBox.toggle();
					// 遍历所有checkbox 设置为false
					int g = nodeOrgFList.size();
					int c = nodeOrgFList.get(groupPosition).getNodeOrgChild()
							.size();
					for (int i = 0; i < g; i++) {
						for (int j = 0; j < c; j++) {
							if (ExpandableAdapter
									.getIsSelected().get(j)) {
								ExpandableAdapter
										.getIsSelected().put(i+""+j, false);
							}
						}
					}
					userList.clear();
					// userId="";//重新初始化选择的人
					// 重新赋值
					ExpandableAdapter.getIsSelected().put(
							groupPosition+""+childPosition, holder.checkBox.isChecked());
					if (holder.checkBox.isChecked()) {
						User user = new User();
						user.setUserId(nodeOrgFList.get(groupPosition)
								.getNodeOrgChild().get(childPosition)
								.getUserid());
						user.setUserName(nodeOrgFList.get(groupPosition)
								.getNodeOrgChild().get(childPosition)
								.getUsername());
						// parent.getChildAt(position).setBackgroundColor(Color.rgb(123,
						// 123, 123));//改变item的背景
						userList.add(user);
					}
					dataChanged(groupPosition);
				} else {
					// 多选
					// 取得ViewHolder对象,这样就省去了通过层层的findViewById去实例化我们需要的cb实例的步骤
					ChildsHander holder = (ChildsHander) v.getTag();
					// 改变CheckBox的状态
					holder.checkBox.toggle();
					// 将CheckBox的选中状况记录下来
					ExpandableAdapter.getIsSelected().put(//对与子item的标记需要特别方式,这与listview的区别之一
							groupPosition+""+childPosition, holder.checkBox.isChecked());
					// 调整选定条目
					// userId="";//重新初始化选择的人
					if (holder.checkBox.isChecked() == true) {
						User user = new User();
						user.setUserId(nodeOrgFList.get(groupPosition)
								.getNodeOrgChild().get(childPosition)
								.getUserid());
						user.setUserName(nodeOrgFList.get(groupPosition)
								.getNodeOrgChild().get(childPosition)
								.getUsername());
						userList.add(user);
					} else {//多选时候一下方式写 不会报出数组越界异常
						int length = userList.size();
						for (int i = 0; i < length; i++) {

							if (nodeOrgFList.get(groupPosition)
									.getNodeOrgChild().get(childPosition)
									.getUserid()
									.equals(userList.get(i).getUserId())) {
								userList.remove(i);
								length = length - 1;
								dataChanged(groupPosition);
							}
						}
					}
				}

				return true;
			}

			
		});

以上适配,按理说能适配大部分类似listview的控件。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值