在Android开发中经常遇到使用ListView的情况,有时候需要的不仅仅是列表显示,还有长按列表进行多选,并且批量删除的情况,在这里记录一下自己的所学。

先上效果图:

几个需要用到的核心方法:

//设置多选模式,下面的方法基于设置多选模式
list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); //获取Item选择状态:
list.isItemChecked(i); //设置Item选择状态
list.setItemChecked(i, true); //清除全部选中状态
list.clearChoices();

简述原理

多选模式下,ListView在触发OnItemClick时会设置Item为true,再点一次为false,

我们只需创建一个isMultiplSelectionMode来传递判断当前为多选模式,

在全选时遍历list.setItemChecked()为true;

反选时遍历list.isItemChecked(i)为true的set为false,false则为true,

删除时直接遍历list.isItemChecked(i)为true的在适配器上直接remove删除即可

假装深入源码

我们知道ListView继承AbsListView,

通过查看他的源码的isItemChecked方法,可以看到

...
public boolean isItemChecked(int position) {
if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) {
return mCheckStates.get(position);
} return false;
}
...

首先判断了当前选择模式不等于默认的单选模式 && mCheckStates 不为空的时候从这个mCheckStates去获取当前的item的选择状态,那我们再来看看这个mCheckStates到底是什么?

    /**
* Running state of which positions are currently checked
*/
SparseBooleanArray mCheckStates;

mCheckStates是SparseBooleanArray的实例,SparseBooleanArray实现了Cloneable接口,再往下就离题了,现在知道了mCheckStates本质是一个保存着Boolean的Array,并且这个Array与Items有关系,setItemChecked/isItemChecked都使用了mCheckStates,获取的就是Item的状态,逻辑他已经帮我们写好,我们只用用好isItemChecked即可。

(好像说了和没说一样,尴尬了|;)

直接上源码把

activity_main.xml

先界面:1个显示选择个数的TextView,3个Button,1个ListView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"> <LinearLayout
android:visibility="gone"
android:id="@+id/ItemToolBar"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选择了0项"
android:id="@+id/counttext"/> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全选"
android:id="@+id/all"/> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="反选"
android:id="@+id/unall"/> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除"
android:id="@+id/del"/> </LinearLayout> <ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mylistview"/> </LinearLayout>

listview_item.xml

当然还有Item项的界面,简单点,两个TextView,一个标题,一个内容

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/lv_text1"/> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="@+id/lv_text2"/> </LinearLayout>

MyAdapter.java

ListView的适配器,重写了getView方法,让当前可视部分的项目状态为选中时改变背景颜色,关于geiView的ViewHolder部分可以看这的文章【Android开发中常用的ListView列表的优化方式ViewHolder】,简而言之就是一种列表优化方式。

public class MyAdapter extends BaseAdapter {

   public ArrayList<HashMap<String, Object>> balistItem = new ArrayList<HashMap<>>();

    @Override
public int getCount() {
return balistItem.size();
} @Override
public long getItemId(int p1) {
return p1);
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = View.inflate(MainActivity.CONTEXT, R.layout.listview_item, null);
viewHolder.title = convertView.findViewById(R.id.lv_text1);
viewHolder.text = convertView.findViewById(R.id.lv_text2);
convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder)convertView.getTag();
} viewHolder.title.setText(balistItem.get(position).get("标题").toString());
viewHolder.text.setText(balistItem.get(position).get("内容").toString()); //判断position位置是否被选中,改变颜色
if (MainActivity.list.isItemChecked(position) && MainActivity.isMultipleSelectionMode) {
convertView.setBackgroundColor(0xffff521d);
} else {
convertView.setBackgroundColor(0xff1E90FF);
}
return convertView;
} public MyAdapter(List<? extends Map<String, ?>> data) {
this.balistItem = (ArrayList<HashMap<String, Object>>) data;
} private static class ViewHolder {
TextView title;
TextView text; public static ViewHolder newsInstance(View convertView) {
ViewHolder holder = (ViewHolder) convertView.getTag(); if (holder == null) {
holder = new ViewHolder();
holder.title = convertView.findViewById(R.id.lv_text1);
holder.text = convertView.findViewById(R.id.lv_text2);
convertView.setTag(holder);
} return holder;
} }
}

MainActivity.java

创建数据,并添加至适配器,设置长按进入多选模式,

public class MainActivity extends AppCompatActivity {

    static ListView list;
static MyAdapter listItemAdapter;//适配器
static boolean isMultipleSelectionMode;//判断进入多选模式
public static ArrayList<HashMap<String, Object>> AdapterList = new ArrayList<>(); //数据 public static Context CONTEXT;
TextView counttext;
LinearLayout ItemToolBar; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CONTEXT = this.getApplicationContext();
//初始化数据
initData(); counttext = this.findViewById(R.id.counttext);//选中时更改的textview
ItemToolBar = this.findViewById(R.id.ItemToolBar);//多选模式的工具栏 list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listItemAdapter = new MyAdapter(AdapterList); //新建并配置ArrayAapeter
list.setAdapter(listItemAdapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override
public void onItemClick(AdapterView<?> p, View v, int index,
long arg3) {
if (isMultipleSelectionMode) {
setCountChange(); }
listItemAdapter.notifyDataSetChanged(); }
}); list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long itemId) { if (isMultipleSelectionMode) {
ItemToolBar.setVisibility(View.GONE);
isMultipleSelectionMode = false; list.clearChoices();//取消选中状态
Toast.makeText(CONTEXT, "退出多选模式", Toast.LENGTH_LONG).show();
} else {
ItemToolBar.setVisibility(View.VISABLE); isMultipleSelectionMode =true;
listItemAdapter.notifyDataSetChanged();
//多选模式
Toast.makeText(CONTEXT, "进入多选模式", Toast.LENGTH_LONG).show();
for(int i = 0;i < listItemAdapter.balistItem.size();i++){
Log.d("del","Item" + i + "的状态:" + list.isItemChecked(i)); } return true; } listItemAdapter.notifyDataSetChanged();
setCountChange(); return false;
}
});
//设置按钮单机事件绑定
setButtonClick(); }
public void setCountChange(){
counttext.setText("选中了" + list.getCheckedItemCount() +"项");
} public void initData(){
list = this.findViewById(R.id.mylistview); for(int i = 0;i< 5;i++){
HashMap<String,Object> map = new HashMap<>();
map.put("标题","这是标题" + i);
map.put("内容","这是内容" + i);
AdapterList.add(map);
}
} public void setButtonClick(){
Button all = this.findViewById(R.id.all);
Button unall = this.findViewById(R.id.unall);
Button del = this.findViewById(R.id.del); all.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for(int i = 0;i < listItemAdapter.balistItem.size();i++){
list.setItemChecked(i,true);
}
setCountChange();
}
}); unall.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for(int i = 0;i < listItemAdapter.balistItem.size();i++){
if(list.isItemChecked(i)){
list.setItemChecked(i,false);
list.setItemChecked(i,false);
}else {
list.setItemChecked(i,true);
}
}
setCountChange();
}
}); del.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { for(int i = 0;i < listItemAdapter.balistItem.size();i++){
if(list.isItemChecked(i)){
listItemAdapter.balistItem.remove(i);
listItemAdapter.notifyDataSetChanged();
}
}
list.clearChoices();
setCountChange();
}
}); } }

demo apk文件下载地址:https://files.cnblogs.com/files/zzerx/app-debug(1).apk

Android ListView的批量处理(多选/反选/删除)的更多相关文章

  1. Jquery 1.8全选反选删除选中项实现

    JQuery1.6以后,Prop的出现,让1.6以下的全选反选效果全部失效了.以下是修正后的版本: 全选反选效果: $(".checkbox").click(function () ...

  2. Vue-表单验证-全选-反选-删除-批量删除

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  3. [整] Android ListView 去除边缘阴影、选中色、拖动背景色等

    以下是通过XML定义的方式实现,如果需要通过代码实现,找到对应是set方式设置即可. 去除ListView滑到顶部和底部时边缘的黑色阴影: android:fadingEdge="none& ...

  4. php对表格进行批量操作如全选反选删除功能

    <!DOCTYPE> <html> <head> <meta http-equiv="content-type" content=&quo ...

  5. android ListView内数据的动态添加与删除

    main.xml 文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns ...

  6. Android ListView实现仿iPhone实现左滑删除按钮

    需要自定义ListView.这里就交FloatDelListView吧. 复写onTouchEvent方法.如下: @Override public boolean onTouchEvent(Moti ...

  7. Android ListView批量选择(全选、反选、全不选)

    APP的开发中,会常遇到这样的需求:批量取消(删除)List中的数据.这就要求ListVIew支持批量选择.全选.单选等等功能,做一个比较强大的ListView批量选择功能是很有必要的,那如何做呢? ...

  8. android UI进阶之实现listview中checkbox的多选与记录

    今天继续和大家分享涉及到listview的内容.在很多时候,我们会用到listview和checkbox配合来提供给用户一些选择操作.比如在一个 清单页面,我们需要记录用户勾选了哪些条目.这个的实现并 ...

  9. 【转】android UI进阶之实现listview中checkbox的多选与记录--不错

    原文网址:http://www.cnblogs.com/notice520/archive/2012/02/17/2355415.html 今天继续和大家分享涉及到listview的内容.在很多时候, ...

随机推荐

  1. CCF_ 201409-3_字符串匹配

    水. #include<cstdio> #include<iostream> #include<cstring> using namespace std; int ...

  2. 【原创】为什么Mongodb索引用B树,而Mysql用B+树?

    引言 好久没写文章了,今天回来重操旧业.毕竟现在对后端开发的要求越来越高,大家要做好各种准备. 因此,大家有可能遇到如下问题 为什么Mysql中Innodb的索引结构采取B+树? 回答这个问题时,给自 ...

  3. 快速应用开发(RAD)平台 - 20 年的演进

    过去几年中,现代软件开发的整体环境发生了巨大的变化.对我个人来说,这种变化与宇宙的加速膨胀差不多.第二个千年刚到来时,产业的发展看起来还不是那么快,只是逐步在前进.现在技术发展的复杂度和多样性已经可以 ...

  4. LVS 介绍 原理

    一. LVS简介       LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器, 是一个由章文嵩博士发起的自由软件项目,它的官方站点是www.linuxvirtual ...

  5. Linux 软件安装卸载 (源码、rpm)

    Linux下软件的安装主要有两种不同的形式.第一种安装为源码安装,文件名为xxx.tar.gz压缩包为主;以第一种方式发行的软件多为以源码形式发送的.第二种方式则是另一种安装文件名为xxx.i386. ...

  6. 修改定时清理 /tmp 目录下的文件

    初衷 默认系统是超过 30 天不访问的文件自动清除的,但是有时候硬盘用得紧可以考虑修改周期 设置方法 编辑配置文件:vim /etc/cron.daily/tmpwatch #! /bin/sh fl ...

  7. C#基础知识学习(2)string类中的方法

    1.Compare 比较字符串 用来比较2个字符串的长度大小和值是否相同,相同则返回0,当x比y小返回-1,否则返回1,如果长度相同,且值不同,则返回1,代码如下 public static void ...

  8. Hibernate框架预览以及基础介绍

    前言 从本节我们开始进入到对于Hibernate框架的学习,当前Hibernate框架还未正式发布6.0稳定版本,所以这里我们以5.4.12Final版本进行讲解. Hibernate框架 Hiber ...

  9. centos7安装postgresql和postgis

    1.安装步骤 -- 安装对应的rpm文件(其他系统的rpm包,请自行到https://yum.postgresql.org/下载)yum install -y https://download.pos ...

  10. php面试笔记(6)-php基础知识-正则表达式考点

    本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而正则表达式相关 ...