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>


ListView中Item的布局:

包含一个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,实现批量删除 源代码下载


更多相关文章

  1. Android(安卓)存储:Internal Storage的用法以及与External storag
  2. Android中Activity生命周期详解
  3. Android(安卓)JNI入门第二篇――Java参数类型与本地参数类型对照
  4. Android笔记---四大组件之Content Provider内容提供者详解
  5. android 实现有阻尼下拉/上拉刷新列表
  6. Android混合开发之WebViewJavascriptBridge实现JS与java安全交互
  7. Android(安卓)常见面试题
  8. Android(安卓)Audio System 之一:AudioTrack如何与AudioFlinger交
  9. Android(安卓)多个Activity之间共享类(数据)——Application Conte

随机推荐

  1. Google Android介绍..
  2. android的intent使用方法
  3. Android核心分析---Android电话系统
  4. 如何在 iOS、Android、macOS、Windows 之
  5. Android View学习示例
  6. Hello, Android(安卓)深入(二)
  7. Android设计登陆界面
  8. 【Android(安卓)开发教程】解决Intent-Fi
  9. [置顶] Android学习之--prelink
  10. android获取程序安装时间