Android开发中经常会遇到单选多选这种问题,简单的做法就是在Adapter里面做处理。
思路:
1.用一个状态位记录Adapter当前是选择模式还是正常模式
2.用一个int型变量记录选中的item的position
3.在getView方法中对Adapter的跟布局进行LongClick监听,进入选择模式
4.开放接口给外部或者内部结束选择模式
那么下面开始敲代码实现单选Adapter
首先写一个接口对Adapter的状态进行监听
/**
* 单选或者多选适配器选择模式变化时候的监听器
*
* @author zhanjixun
*
*/
public interface OnSelectModeChangeListener {
/**
* 进入选择模式的时候调用
*
* @param adapter
*/
public void onSelectModeStart(Adapter adapter);
/**
* 退出选择模式的时候调用
*
* @param adapter
*/
public void onSelectModeEnd(Adapter adapter);
}
然后开始写我们的单选适配器,这里偷个小懒,我不直接继承BaseAdapter,为了简化开发,我用了我封装好的一个EasyAdapter,它也是继承自BaseAdapter的,具体代码可以看我之前的一篇博客Android中Adapter的封装
public class RadioAdapter extends EasyAdapter<String> {
private boolean selectMode = false;
private int selectedItem = 0;
private OnSelectModeChangeListener mListener;
public RadioAdapter(Context context, List<String> list) {
super(context, list);
setLayoutId(R.layout.item_listview);
}
@Override
protected void convert(final int position, ViewHolder holder, String paramT) {
View convertView = holder.getConvertView();
if (isSelectMode()) {
convertView.setOnLongClickListener(null);
convertView.setOnClickListener(new OnItemClickListener(position));
} else {
convertView.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
setSelectMode(!isSelectMode(), position);
return false;
}
});
convertView.setOnClickListener(null);
}
// 设置CheckBox
CheckBox checkBox = holder.findViewById(R.id.checkBox);
if (isSelectMode()) {
checkBox.setVisibility(View.VISIBLE);
checkBox.setChecked(selectedItem == position);
} else {
checkBox.setVisibility(View.GONE);
}
}
/**
* 返回选中的item,直接返回数据
*
* @return
*/
public String getSelectedItem() {
return mList.get(selectedItem);
}
/**
* 设置模式转换监听
*
* @param listener
*/
public void setOnSelectModeChangeListener(
OnSelectModeChangeListener listener) {
mListener = listener;
}
/**
* 是否是选择模式
*
* @return
*/
public boolean isSelectMode() {
return selectMode;
}
/**
* position用来设置进入选择模式时候默认选中的item
*
* @param selectMode
* @param position
*/
protected void setSelectMode(boolean selectMode, int position) {
if (selectMode) {
selectedItem = position;
}
// 监听回调
if (mListener != null) {
if (selectMode) {
mListener.onSelectModeStart(this);
} else if (selectMode == false) {
mListener.onSelectModeEnd(this);
}
}
this.selectMode = selectMode;
notifyDataSetChanged();
}
/**
* 设置模式,选中的item
*
* @param selectMode
*/
public void setSelectMode(boolean selectMode) {
setSelectMode(selectMode, 0);
}
private class OnItemClickListener implements View.OnClickListener {
private int postion = 0;
public OnItemClickListener(int postion) {
this.postion = postion;
}
@Override
public void onClick(View v) {
selectedItem = postion;
notifyDataSetChanged();
}
}
/**
* 模式变化监听器
*
* @author zhanjixun
*
*/
public interface OnSelectListener {
public void onSelectModeEnd();
public void onSelectModeStart();
}
}
这里是用到的布局文件:item_listview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:clickable="false"
android:visibility="gone" />
<TextView
android:id="@+id/mainTextView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="25dp"
android:gravity="center_vertical"
android:singleLine="true"
android:textSize="25sp" />
</LinearLayout>
其实多选的实现也跟单选差不多,直接帖代码了,这里用的一个封装的类,也就是这说这个类还不能做直接拿来用的Adapter,需要写一个类继承这个类来实现一些特定的处理,比如,显示CheckBox
/**
* 封装的多选适配器
*
* @author zhanjixun
*
* @param <T>
*/
public class MultipleChoiceAdapter<T> extends EasyAdapter<T> {
private EasyLog log = new EasyLog(this.getClass().getName());
/**
* 模式变换监听器
*/
protected OnSelectModeChangeListener mListener;
/**
* 模式状态位
*/
protected boolean selectMode = false;
/**
* 是否选中的标识位
*/
protected SparseBooleanArray selectedItems = new SparseBooleanArray();
public MultipleChoiceAdapter(Context context, List<T> list) {
super(context, list);
}
@Override
protected void convert(final int position, ViewHolder holder, T item) {
View convertView = holder.getConvertView();
convertView.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
setSelectMode(!isSelectMode(), position);
return false;
}
});
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
boolean choice = !selectedItems.get(position);
selectedItems.put(position, choice);
if (choice) {
log.i("选中position:" + position);
} else {
log.w("撤销选中position:" + position);
}
notifyDataSetChanged();
}
});
}
/**
* 设置模式转换监听
*
* @param listener
*/
public void setOnSelectModeChangeListener(
OnSelectModeChangeListener listener) {
mListener = listener;
}
/**
* 是否是选择模式
*
* @return
*/
public boolean isSelectMode() {
return selectMode;
}
/**
* 设置模式,选中的item
*
* @param selectMode
*/
protected void setSelectMode(boolean selectMode, int position) {
if (selectMode) {
selectedItems.clear();
selectedItems.put(position, true);
log.i("进入选择模式");
} else {
log.i("退出选择模式");
}
if (mListener != null) {
if (selectMode) {
mListener.onSelectModeStart(this);
} else if (selectMode == false) {
mListener.onSelectModeEnd(this);
}
} else {
log.e("监听器为空");
}
this.selectMode = selectMode;
notifyDataSetChanged();
}
/**
* 设置模式,选中的item
*
* @param selectMode
*/
public void setSelectMode(boolean selectMode) {
setSelectMode(selectMode, 0);
}
/**
* 获取已经选中的item
*
* @return
*/
public List<T> getSelectedItems() {
List<T> list = new ArrayList<T>();
for (int index = 0; index < selectedItems.size(); index++) {
if (selectedItems.valueAt(index)) {
list.add(mList.get(selectedItems.keyAt(index)));
}
}
return list;
}
}