作者:白珍茜登陆_585 | 来源:互联网 | 2023-06-20 18:37
Android开发——listview中嵌套checkBox复选框实现单选、全选删除列表内容listView中嵌套复选框进行条目的选中删除操作,我们经常会用到,比如:购物车清单中的商品添加删除,及通讯
Android开发——listview中嵌套checkBox复选框实现单选、全选删除列表内容
listView中嵌套复选框进行条目的选中删除操作,我们经常会用到,比如:购物车清单中的商品添加删除,及通讯录、短信的删除等功能。
话不多说,先上运行效果图
若要实现listview中嵌套checkbox复选框的单选、全选列表删除功能,我们需要实现一个自定义适配器;
整体实现思路:
(1)实现一个自定义适配器继承自BaseAdapter;
(2)在子布局中的chebox属性:一定要加上两个属性:
android:clickable="false"
android:focusable="false"
(3)在删除列表内容时不能直接在数据源中进行操作,要新建一个存储勾选要删除的内容的集合,否则会报异常
(4)在删除之后,把存储删除内容的集合调用clear()方法清空集合中的内容,并调用notifyDataSetChanged()方法通知适配器更新UI
(5)checkbox嵌套在listview中,要把复选框的选中状态保存下来;
布局代码:
activity_main.xml
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:cOntext="com.stx.xhb.listviewcheckdelete.MainActivity">
android:layout_
android:layout_
android:orientation="horizontal">
android:layout_
android:layout_
android:layout_weight="1">
android:id="@+id/lv_data"
android:layout_
android:layout_>
子布局代码:
item_layout.xml
android:layout_
android:layout_
android:orientation="horizontal">
android:layout_
android:layout_
android:layout_weight="1">
android:layout_
android:layout_
android:background="@mipmap/ic_launcher" />
android:layout_
android:layout_
android:orientation="vertical">
android:id="@+id/tv_name"
android:layout_
android:layout_
android:text="姓名"
android:textSize="18sp" />
android:id="@+id/tv_phone"
android:layout_
android:layout_
android:text="电话"
android:textSize="18sp" />
android:layout_
android:layout_>
android:id="@+id/ch_delete"
android:layout_
android:layout_
android:layout_gravity="right"
android:clickable="false"
android:focusable="false" />
自定义适配器
MyAdapter.java
package com.stx.xhb.listviewcheckdelete;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import java.util.List;
/**
* 自定义适配器
* Created by xhb on 2015/12/19.
*/
public class MyAdapter extends BaseAdapter {
private ListView lv_data;
//定义一个数据源的引用
private List- data;
private Context context;
public MyAdapter(Context context,ListView lv_data) {
if (context instanceof MainActivity) {
this.cOntext= context;
this.lv_data=lv_data;
data=((MainActivity)this.context).getData();
}
}
/**
* 获取当前子view的id(就是listview中的每一个条目的位置)
* @param position
* @return 返回当前id
*/
@Override
public long getItemId(int position) {
return position;
}
/**
* 获取当前子view对应的值
* @param position 当前子view(条目)的id(位置)
* @return 返回当前对应的值 该值为object类型
*/
@Override
public Object getItem(int position) {
return data.get(position);
}
/**
* 定义coverView的Recyler(缓存),该类名自定义的
*/
class ViewHodler{
TextView tvName;
TextView tvPhone;
CheckBox ch_delete;
}
/**
* 核心代码
* @param position 当前子view的id
* @param convertView 缓存布局(该view与子view保持一致)
* @param parent 父容器(即当前listview)
* @return 返回当前子view(包含布局及具体的数据)
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//布局生成器(抽象类)
LayoutInflater layoutInflater=LayoutInflater.from(this.context);
//声明缓存
ViewHodler viewHodler=null;
//重新创建布局及缓存
if (cOnvertView==null){
//创建缓存布局
cOnvertView=layoutInflater.inflate(R.layout.item_layout,parent,false);
//产生缓存
viewHodler=new ViewHodler();
viewHodler.tvName=(TextView)convertView.findViewById(R.id.tv_name);
viewHodler.tvPhOne=(TextView)convertView.findViewById(R.id.tv_phone);
viewHodler.ch_delete= (CheckBox) convertView.findViewById(R.id.ch_delete);
//把缓存的布局放在converview中,避免重复获取布局,提升效率
convertView.setTag(viewHodler);
}else{
//使用缓存的中的布局
viewHodler= (ViewHodler) convertView.getTag();
}
//为缓存的布局ViewHodler控件设置新的数据
Item currItem=data.get(position);
viewHodler.tvName.setText(currItem.getName());
viewHodler.tvPhone.setText(currItem.getPhone());
viewHodler.ch_delete.setChecked(currItem.getChecked());
//listView单个条目事件监听
lv_data.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
/* ViewHodler viewHodler= (ViewHodler) view.getTag();
//切换条目上复选框的选中状态
viewHodler.ch_delete.toggle();
data.get(position).setChecked(viewHodler.ch_delete.isChecked());*/
parent.getItemAtPosition(position);
}
});
//返回多次生成的子View给适配器
return convertView;
}
/**
* 获取数据中要在listview中显示的条目
* @return 返回数据的条目
*/
@Override
public int getCount() {
return this.data!=null?this.data.size():0;
}
}
MainActivity.java
package com.stx.xhb.listviewcheckdelete;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* @author xhb
* listView中嵌入复选框实现单选、全选删除列表条目
* 注意事项:
*1.子布局中的checkBox以下两个属性(会导致onItemClickListener(即单个条目的点击事件)失效):
* android:clickable="false"
* android:focusable="false"
*2.在删除过程中,首先应该把勾选的删除内容添加到一个新的删除集合中,不能直接在数据源中进行删除,否则会报异常
*3.在删除之后,并把删除集合中的内容清空
*/
public class MainActivity extends AppCompatActivity {
//定义listview
private ListView lv_data;
//定义控件
private Button btn_delete;
private CheckBox che_all;
//声明一个集合(数据源)
private List- data;
//定义自定义适配器
private MyAdapter myAdapter;
//给数据源添加数据
private void initdata(){
data=new ArrayList<>();
for (int i=0;i<=10;i++){
data.add(new Item("小明"+i,"110"+i,false));
}
}
//返回数据给MyAdapter使用
public List- getData(){
return this.data;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取listView
lv_data= (ListView) findViewById(R.id.lv_data);
//获取控件
btn_delete= (Button) findViewById(R.id.btn_delete);
che_all= (CheckBox) findViewById(R.id.che_all);
//初始化数据源
initdata();
//实例化自定义适配器,把listview传到自定义适配器中
myAdapter =new MyAdapter(this,lv_data);
//绑定适配器
lv_data.setAdapter(myAdapter);
//初始化事件监听
initlistener();
}
/**
* 初始化事件监听方法
*/
private void initlistener() {
/**
* 全选复选框设置事件监听
*/
che_all.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (data.size()!=0) {//判断列表中是否有数据
if (isChecked) {
for (int i = 0; i data.get(i).setChecked(true);
}
//通知适配器更新UI
myAdapter.notifyDataSetChanged();
} else {
for (int i = 0; i data.get(i).setChecked(false);
}
//通知适配器更新UI
myAdapter.notifyDataSetChanged();
}
}else{//若列表中没有数据则隐藏全选复选框
che_all.setVisibility(View.GONE);
}
}
});
//删除按钮点击事件
btn_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//创建一个要删除内容的集合,不能直接在数据源data集合中直接进行操作,否则会报异常
List- deleSelect = new ArrayList
- ();
//把选中的条目要删除的条目放在deleSelect这个集合中
for (int i = 0; i if (data.get(i).getChecked()) {
deleSelect.add(data.get(i));
}
}
//判断用户是否选中要删除的数据及是否有数据
if (deleSelect.size() != 0 && data.size() != 0) {
//从数据源data中删除数据
data.removeAll(deleSelect);
//把deleSelect集合中的数据清空
deleSelect.clear();
//把全选复选框设置为false
che_all.setChecked(false);
//通知适配器更新UI
myAdapter.notifyDataSetChanged();
} else if (data.size() == 0) {
Toast.makeText(MainActivity.this, "没有要删除的数据", Toast.LENGTH_SHORT).show();
} else if (deleSelect.size() == 0) {
Toast.makeText(MainActivity.this, "请选中要删除的数据", Toast.LENGTH_SHORT).show();
}
}
});
}
}
Item.java
package com.stx.xhb.listviewcheckdelete;
/**
* 子布局控件属性实体类
* Created by xhb on 2015/12/19.
*/
public class Item {
private String name;
private String phone;
private Boolean checked;
public Item(String name, String phone,Boolean checked) {
this.name = name;
this.phOne= phone;
this.checked = checked;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phOne= phone;
}
public Boolean getChecked() {
return checked;
}
public void setChecked(Boolean checked) {
this.checked = checked;
}
}
源码下载地址: