Android(安卓)长按Listview显示CheckBox,实现批量删除
ListView实现的列表,如果长按某一个Item,可以显示右边隐藏的CheckBox,从而实现批量删除的功能。效果如图所示。
在网上看到一篇博客:Android 长按Listview显示CheckBox,实现批量删除。但是长按ListView的某一个Item后,其Item的CheckBox并未被选中,需要重新选择。
这篇博客虽然实现了长按ListView显示CheckBox并能批量删除的功能,但是用户体验并不让我满意,所以参考该博文,自己动手写了个项目。
在长按ListView的时候,长按的Item中的CheckBox会被选中,不用重新选择。之后可以继续选择其他Item的CheckBox,并实现了批量删除的功能。
自己写的例子,并未进行完善的测试,如有bug,欢迎指出。
实现思路如下:
1、在ListView的Item布局中放入CheckBox,设置其属性为不可见。新建一个list_delete,用来记录有哪些Item被选中。设置一个标识位isMultiSelect,记录是否处于多选状态。
2、在长按的时候,根据长按Item的position重新加载ListView的适配器,显示出CheckBox,根绝position将长按的Item的CheckBox设为选中状态。并将isMultiSelect设置为true。
3、处于多选状态时(isMultiSelect为true),当点击别的Item,将其数据添加到list_delete中,并勾选上相应的CheckBox。
4、底部的删除,撤销按钮也是在多选状态时才显示。点击删除时,遍历比较list_delete与数据源中的数据,相同的则从数据源中移除。完成后重新显示数据源。
具体实现代码如下:
主页面布局:
主页面布局包含一个ListView和一个隐藏布局,隐藏布局里有两个Button和一个TextView,其visibility属性默认为gone,当监听到长按事件时显示。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > </ListView> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:visibility="gone" > <Button android:id="@+id/bt_cancel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="取消选择" /> <TextView android:id="@+id/tv_sum" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="共计" /> <Button android:id="@+id/bt_delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="删除" /> </LinearLayout></LinearLayout>
包含一个TextView和一个隐藏的CheckBox,当监听到长按事件时,CheckBox显示,注意事项请看代码中的注释
<?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" > <TextView android:id="@+id/tv_name" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="30sp" /> <!-- CheckBox的clickable属性要设置为false 否则点击CheckBox只会触发它自己的事件 不会触发ListView中Item的点击事件 --> <CheckBox android:id="@+id/cb_select" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:visibility="invisible" /></LinearLayout>
MainActivity代码:
注意事项请看代码中的注释
package com.example.listviewitemmulselect;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import android.os.Bundle;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.View.OnLongClickListener;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.Button;import android.widget.CheckBox;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.TextView;public class MainActivity extends Activity implements OnClickListener {private static final int NOSELECT_STATE = -1;// 表示未选中任何CheckBoxprivate ListView listView;private Button bt_cancel, bt_delete;private TextView tv_sum;private LinearLayout linearLayout;private List<String> list = new ArrayList<String>();// 数据private List<String> list_delete = new ArrayList<String>();// 需要删除的数据private boolean isMultiSelect = false;// 是否处于多选状态private MyAdapter adapter;// ListView的Adapter@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);listView = (ListView) findViewById(R.id.listView1);bt_cancel = (Button) findViewById(R.id.bt_cancel);bt_delete = (Button) findViewById(R.id.bt_delete);tv_sum = (TextView) findViewById(R.id.tv_sum);linearLayout = (LinearLayout) findViewById(R.id.linearLayout);bt_cancel.setOnClickListener(this);bt_delete.setOnClickListener(this);// 设置初始数据list = new ArrayList<String>();for (int i = 0; i < 20; i++) {String str = "Item" + i;list.add(str);}// 未选中任何Item,position设置为-1adapter = new MyAdapter(MainActivity.this, list, NOSELECT_STATE);listView.setAdapter(adapter);}private class MyAdapter extends BaseAdapter {private List<String> list;private LayoutInflater inflater;private HashMap<Integer, Integer> isCheckBoxVisible;// 用来记录是否显示checkBoxprivate HashMap<Integer, Boolean> isChecked;// 用来记录是否被选中@SuppressLint("UseSparseArrays")public MyAdapter(Context context, List<String> list, int position) {inflater = LayoutInflater.from(context);this.list = list;isCheckBoxVisible = new HashMap<Integer, Integer>();isChecked = new HashMap<Integer, Boolean>();// 如果处于多选状态,则显示CheckBox,否则不显示if (isMultiSelect) {for (int i = 0; i < list.size(); i++) {isCheckBoxVisible.put(i, CheckBox.VISIBLE);isChecked.put(i, false);}} else {for (int i = 0; i < list.size(); i++) {isCheckBoxVisible.put(i, CheckBox.INVISIBLE);isChecked.put(i, false);}}// 如果长按Item,则设置长按的Item中的CheckBox为选中状态if (isMultiSelect && position >= 0) {isChecked.put(position, true);}}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn list.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn list.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {final ViewHolder viewHolder;if (convertView == null) {viewHolder = new ViewHolder();convertView = inflater.inflate(R.layout.item_layout, null);viewHolder.tv_Name = (TextView) convertView.findViewById(R.id.tv_name);viewHolder.cb = (CheckBox) convertView.findViewById(R.id.cb_select);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}final String str = list.get(position);viewHolder.tv_Name.setText(str);// 根据position设置CheckBox是否可见,是否选中viewHolder.cb.setChecked(isChecked.get(position));viewHolder.cb.setVisibility(isCheckBoxVisible.get(position));// ListView每一个Item的长按事件convertView.setOnLongClickListener(new onMyLongClick(position, list));/* * 在ListView中点击每一项的处理 * 如果CheckBox未选中,则点击后选中CheckBox,并将数据添加到list_delete中 * 如果CheckBox选中,则点击后取消选中CheckBox,并将数据从list_delete中移除 */convertView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// 处于多选模式if (isMultiSelect) {if (viewHolder.cb.isChecked()) {viewHolder.cb.setChecked(false);list_delete.remove(str);} else {viewHolder.cb.setChecked(true);list_delete.add(str);}tv_sum.setText("共选择了" + list_delete.size() + "项");}}});return convertView;}class ViewHolder {public TextView tv_Name;public CheckBox cb;}// 自定义长按事件class onMyLongClick implements OnLongClickListener {private int position;private List<String> list;// 获取数据,与长按Item的positionpublic onMyLongClick(int position, List<String> list) {this.position = position;this.list = list;}// 在长按监听时候,切记将监听事件返回ture@Overridepublic boolean onLongClick(View v) {isMultiSelect = true;list_delete.clear();// 添加长按Item到删除数据list中list_delete.add(list.get(position));linearLayout.setVisibility(View.VISIBLE);tv_sum.setText("共选择了" + list_delete.size() + "项");for (int i = 0; i < list.size(); i++) {adapter.isCheckBoxVisible.put(i, CheckBox.VISIBLE);}// 根据position,设置ListView中对应的CheckBox为选中状态adapter = new MyAdapter(MainActivity.this, list, position);listView.setAdapter(adapter);return true;}}}@Overridepublic void onClick(View v) {switch (v.getId()) {// 取消选择case R.id.bt_cancel:isMultiSelect = false;// 退出多选模式list_delete.clear();// 清楚选中的数据// 重新加载Adapteradapter = new MyAdapter(MainActivity.this, list, NOSELECT_STATE);listView.setAdapter(adapter);linearLayout.setVisibility(View.GONE);break;// 删除case R.id.bt_delete:isMultiSelect = false;// 将数据从list中移除for (int i = 0; i < list.size(); i++) {for (int j = 0; j < list_delete.size(); j++) {if (list.get(i).equals(list_delete.get(j))) {list.remove(i);}}}list_delete.clear();// 重新加载Adapteradapter = new MyAdapter(MainActivity.this, list, NOSELECT_STATE);listView.setAdapter(adapter);linearLayout.setVisibility(View.GONE);break;default:break;}}}如此,便实现了长按ListView,可以多选,并能批量删除的功能。
项目源码请戳:Android 长按Listview显示CheckBox,实现批量删除 源代码下载
更多相关文章
- Android(安卓)存储:Internal Storage的用法以及与External storag
- Android中Activity生命周期详解
- Android(安卓)JNI入门第二篇――Java参数类型与本地参数类型对照
- Android笔记---四大组件之Content Provider内容提供者详解
- android 实现有阻尼下拉/上拉刷新列表
- Android混合开发之WebViewJavascriptBridge实现JS与java安全交互
- Android(安卓)常见面试题
- Android(安卓)Audio System 之一:AudioTrack如何与AudioFlinger交
- Android(安卓)多个Activity之间共享类(数据)——Application Conte