经常会遇到很多人问,有没有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的控件。