Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能

    xiaoxiao2021-12-15  27

    标签: androidlistview控件checkbox图片   分类: Android(110) 

    目录(?)[+]

    Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能


    这个控件还是挺复杂的,也是项目中应该算是比较常用的了,所以写了一个小Demo来讲讲,主要是自定义adapter的用法,加了很多的判断等等等等….我们先来看看实现的效果吧!

    好的,我们新建一个项目LvCheckBox

    我们事先先把这两个布局写好吧,一个是主布局,还有一个listview的item.xml,相信不用多说

    activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="50dp" android:background="#238286" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="ListView绑定CheckBox" android:textColor="#fff" /> <TextView android:id="@+id/tv_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="17dp" android:text="增加" android:textColor="#fff" /> </RelativeLayout> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > </ListView> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" > <Button android:id="@+id/btn_detele" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginRight="1dp" android:layout_weight="1" android:background="#238286" android:text="删除" android:textColor="#fff" /> <Button android:id="@+id/btn_select_all" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="1dp" android:layout_weight="1" android:background="#238286" android:text="全选" android:textColor="#fff" /> </LinearLayout> </LinearLayout> 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263

    item.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="50dp" android:gravity="center_vertical" android:orientation="horizontal" > <TextView android:id="@+id/tvTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="15dp" android:layout_weight="7" android:text="text" /> <CheckBox android:id="@+id/cbCheckBox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" /> </LinearLayout> 12345678910111213141516171819202122 12345678910111213141516171819202122

    item.xml只有两个控件,很好理解吧

    初始化控件

    我们用initView()方法来初始化这些控件 private void initView() { tv_add = (TextView) findViewById(R.id.tv_add); tv_add.setOnClickListener(this); btn_detele = (Button) findViewById(R.id.btn_detele); btn_detele.setOnClickListener(this); btn_select_all = (Button) findViewById(R.id.btn_select_all); btn_select_all.setOnClickListener(this); listview = (ListView) findViewById(R.id.listview); } 12345678910 12345678910

    然后继承点击事件,button的和listview的

    implements OnClickListener,OnItemClickListener 1 1

    自定义Adapter

    这里最难的就是adapter了

    1.Bean

    我们为了数据的记录方便,我们提前写一个实体类 package com.lgl.lvcheckbox; public class Bean { private String title; // 构造方法 public Bean(String title) { super(); this.title = title; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } 12345678910111213141516171819202122 12345678910111213141516171819202122

    ListAdapter

    这里所有的都写了注释,也方便大家看清 package com.lgl.lvcheckbox; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.TextView; /** * 自定义适配器 * * @author LGL * */ public class ListAdapter extends BaseAdapter { // 数据集 private List<Bean> list = new ArrayList<Bean>(); // 上下文 private Context mContext; // 存储勾选框状态的map集合 private Map<Integer, Boolean> isCheck = new HashMap<Integer, Boolean>(); // 构造方法 public ListAdapter(Context mContext) { super(); this.mContext = mContext; // 默认为不选中 initCheck(false); } // 初始化map集合 public void initCheck(boolean flag) { // map集合的数量和list的数量是一致的 for (int i = 0; i < list.size(); i++) { // 设置默认的显示 isCheck.put(i, flag); } } // 设置数据 public void setData(List<Bean> data) { this.list = data; } // 添加数据 public void addData(Bean bean) { // 下标 数据 list.add(0, bean); } @Override public int getCount() { // TODO Auto-generated method stub // 如果为null就返回一个0 return list != null ? list.size() : 0; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return list.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder viewHolder = null; View view = null; // 判断是不是第一次进来 if (convertView == null) { view = LayoutInflater.from(mContext).inflate(R.layout.item, null); viewHolder = new ViewHolder(); viewHolder.title = (TextView) view.findViewById(R.id.tvTitle); viewHolder.cbCheckBox = (CheckBox) view .findViewById(R.id.cbCheckBox); // 标记,可以复用 view.setTag(viewHolder); } else { view = convertView; // 直接拿过来用 viewHolder = (ViewHolder) view.getTag(); } // 拿到对象 Bean bean = list.get(position); // 填充数据 viewHolder.title.setText(bean.getTitle().toString()); // 勾选框的点击事件 viewHolder.cbCheckBox .setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // 用map集合保存 isCheck.put(position, isChecked); } }); // 设置状态 if (isCheck.get(position) == null) { isCheck.put(position, false); } viewHolder.cbCheckBox.setChecked(isCheck.get(position)); return view; } // 优化 public static class ViewHolder { public TextView title; public CheckBox cbCheckBox; } // 全选按钮获取状态 public Map<Integer, Boolean> getMap() { // 返回状态 return isCheck; } // 删除一个数据 public void removeData(int position) { list.remove(position); } } 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138

    当然,有些方法是后面写的,我们提前写好,比如删除和增加什么的

    初始化数据

    我们默认总是需要点数据的 private void initData() { // 默认显示的数据 List<Bean> list = new ArrayList<Bean>(); list.add(new Bean("张三")); list.add(new Bean("李四")); list.add(new Bean("王五")); adapter = new ListAdapter(this); adapter.setData(list); listview.setAdapter(adapter); } 1234567891011 1234567891011

    增加数据

    // 添加数据 case R.id.tv_add: adapter.addData(new Bean("刘桂林")); // 通知刷新适配器 adapter.notifyDataSetChanged(); break; 123456 123456

    全选数据

    当我们全选的时候,按钮应该为全不选的,所以这里我们这里有状态的 case R.id.btn_select_all: // 全选——全不选 Map<Integer, Boolean> isCheck = adapter.getMap(); if (btn_select_all.getText().equals("全选")) { adapter.initCheck(true); // 通知刷新适配器 adapter.notifyDataSetChanged(); btn_select_all.setText("全不选"); btn_select_all.setTextColor(Color.YELLOW); } else if (btn_select_all.getText().equals("全不选")) { adapter.initCheck(false); // 通知刷新适配器 adapter.notifyDataSetChanged(); btn_select_all.setText("全选"); btn_select_all.setTextColor(Color.YELLOW); } break; 1234567891011121314151617 1234567891011121314151617

    删除数据

    删除也是要考虑很多因素 // 删除数据 case R.id.btn_detele: // 拿到所有数据 Map<Integer, Boolean> isCheck_delete = adapter.getMap(); // 获取到条目数量,map.size = list.size,所以 int count = adapter.getCount(); // 遍历 for (int i = 0; i < count; i++) { // 删除有两个map和list都要删除 ,计算方式 int position = i - (count - adapter.getCount()); // 判断状态 true为删除 if (isCheck_delete.get(i) != null && isCheck_delete.get(i)) { // listview删除数据 isCheck_delete.remove(i); adapter.removeData(position); } } btn_select_all.setText("全选"); btn_select_all.setTextColor(Color.WHITE); adapter.notifyDataSetChanged(); break; 123456789101112131415161718192021 123456789101112131415161718192021

    这里的

    int position = i - (count - adapter.getCount()); 1 1

    是一个计算方式,当我们删除之后,实际上数组是需要重新排列的,同时按钮也要变回全选状态的

    listview的点击

    我们直接点击也是可以勾选cheakbox选中的 // listview的点击事件 @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // 判断view是否相同 if (view.getTag() instanceof ViewHolder) { // 如果是的话,重用 ViewHolder holder = (ViewHolder) view.getTag(); // 自动触发 holder.cbCheckBox.toggle(); } } 123456789101112 123456789101112

    好的,这样的话就可以实现了,如果不懂的话可以下载本文demo参考,觉得好的点个赞

    Demo下载地址:http://download.csdn.net/detail/qq_26787115/9423306

    转载请注明原文地址: https://ju.6miu.com/read-1000274.html

    最新回复(0)