Expandablelistview与CheckBox+setOnCheckedChangeListener有坑

Expandablelistview是用来处理分组数据的(至少我是这么认为的),如QQ列表。那么我们今天主要来说明Expandablelistview+CheckBox的使用情况,以及注意事项。

现来个我的效果图片:
Expandablelistview与CheckBox+setOnCheckedChangeListener有坑_第1张图片

一、布局实现

1、activity_main:

"1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.myapplication.MainActivity">

    Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:fitsSystemWindows="true"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" >
        <TextView
            android:id="@+id/text_done"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:layout_marginRight="5dp"
            android:clickable="true"
            android:text="Done"
            android:textColor="@color/write"
            android:textSize="@dimen/textSize"/>
    </android.support.v7.widget.Toolbar>
    
        "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="To"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:textColor="@color/write"
            android:textSize="17sp"/>
        "
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/write"
            android:layout_toRightOf="@+id/tv"
            android:layout_marginRight="10dp"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:orientation="horizontal">

                "
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_alignParentLeft="true"
                    android:layout_marginLeft="5dp">
                

            "
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_alignParentRight="true"
                android:background="@null"
                android:hint="Search..."/>
        
    
    "
        android:layout_width ="fill_parent"
        android:layout_height ="wrap_content"
        android:groupIndicator="@null"
        />

有点多,只需要最后一个ExpandableListView

2、listitem_child:

"1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <CheckBox
        android:id="@+id/checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_centerVertical="true"/>
    <ImageView
        android:id="@+id/iv"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@+id/checkbox"/>
    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/iv"
        android:layout_marginTop="5dp"
        android:layout_marginLeft="10dp"
        android:textStyle="bold"
        android:text="aaaaaa"
        android:textSize="20sp"/>
    <TextView
        android:id="@+id/other"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/iv"
        android:layout_below="@+id/name"
        android:layout_marginLeft="10dp"
        android:text="offline"
        android:textSize="18sp"/>
</RelativeLayout>

CheckBox是必须的

3、listitem_group:

"1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:background="#8F8F8F">
 <TextView
     android:id="@+id/group"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:textSize="20sp"
     android:layout_centerVertical="true"
     android:textColor="@color/write"
     android:layout_marginLeft="15dp"
     android:text="A"/>
</RelativeLayout>

组的显示方式,我这只是一个TextView

二、适配器实现

下面重点来了

package util;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.myapplication.R;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import pojo.People;

/**
 * Created by Administrator on 2017/2/24.
 */

public  class  ExpandableAdapter extends BaseExpandableListAdapter{

    public String[] group;
    public Map> child;
    public List checked;
    private Context context;
    private boolean cklickgoup;
    public ExpandableAdapter(Context context) {

        this.context = context;
        checked = new ArrayList<>();
        if (group == null)
            group = new String[]{};
        if (child == null)
            child = new HashMap>() ;
    }

    public void setGroups(String[] group)
    {
        if (group != null)
            this.group = group;
    }

    public void setChild(Map> child)
    {
        if (child != null)
           this.child = child;
    }

    public void setCklickgoup(boolean cklickgoup)
    {
        this.cklickgoup = cklickgoup;
    }

    //获取与给定的组相关的数据,得到数组groups中元素的数据
    public Object getGroup(int groupPosition) {
        return group[groupPosition];
    }

    //获取与孩子在给定的组相关的数据,得到数组children中元素的数据
    public Object getChild(int groupPosition, int childPosition) {
        return child.get(group[groupPosition]).get(childPosition);
    }

    //获取的群体数量,得到groups里元素的个数
    public int getGroupCount() {
        return group.length;
    }

    //取得指定组中的children个数,就是groups中每一个条目中的个数
    public int getChildrenCount(int groupPosition) {
        return child.get(group[groupPosition]).size();
    }

    //获取组在给定的位置编号,即groups中元素的ID
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    //获取在给定的组的children的ID,也就是children中元素的ID
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    //获取一个视图显示给定组,存放groups
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
                             ViewGroup parent) {
        View view = convertView;
        genericView textView;
        if (view == null)
        {
            view = View.inflate(context, R.layout.listitem_group, null);
            textView = new genericView();
            view.setTag(textView);
        }else
        {
            textView = (genericView)view.getTag();
        }
        textView.group = (TextView) view.findViewById(R.id.group);
        textView.group.setText(group[groupPosition].toString());
        return view;
    }

    //获取一个视图显示在给定的组 的儿童的数据,就是存放children
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild,
                             View convertView, ViewGroup parent) {
        View view = convertView;
        childView childview;
        if (view == null)
        {
            view = View.inflate(context, R.layout.listitem_child, null);
            childview = new childView();
            view.setTag(childview);
        }else
        {
            childview = (childView)view.getTag();
        }
        childview.imageView = (ImageView) view.findViewById(R.id.iv);
        childview.name = (TextView) view.findViewById(R.id.name);
        childview.checkBox = (CheckBox) view.findViewById(R.id.checkbox);
        childview.imageView.setBackgroundResource(child.get(group[groupPosition]).get(childPosition).head);
        childview.name.setText(child.get(group[groupPosition]).get(childPosition).name);
        childview.checkBox.setChecked(child.get(group[groupPosition]).get(childPosition).isChecked);
        childview.checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean isChecked = child.get(group[groupPosition]).get(childPosition).isChecked;
                String name = child.get(group[groupPosition]).get(childPosition).name;
                if (!isChecked)
                {
                    child.get(group[groupPosition]).get(childPosition).isChecked = true;
                    checked.add(child.get(group[groupPosition]).get(childPosition));

                }else {
                    child.get(group[groupPosition]).get(childPosition).isChecked = false;
                    for (int i =0;i/孩子在指定的位置是可选的,即:children中的元素是可点击的
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

    //表示孩子是否和组ID是跨基础数据的更改稳定
    public boolean hasStableIds() {
        return true;
    }


    class genericView
    {
        public TextView group;
    }

    class childView
    {
        public CheckBox checkBox;
        public ImageView imageView;
        public TextView name;
        public TextView other;
    }

    public interface CheckListener
    {
        void Checked(List checked);
    }
    CheckListener CheckListener;
    public void getChecked(CheckListener CheckListener)
    {
        this.CheckListener = CheckListener;
    }
}

多选的重点在getChildView方法里面,CheckBox的初始化是用对象里的字段isChecked控制的,每次选择以后就修改isChecked的值就好了,选择结果用的接口回调传递。下面说一下这个地方有个坑,上面代码我用的是CheckBox的setOnClickListener,那么是没问题的,如果你用setOnCheckedChangeListener,那么就很严重了,因为在组的合并展开时可能会触发CheckBox的setOnCheckedChangeListener,为什么是可能会,因为在你CheckBox全部都没选中的时候是不会触发的(注意是全部),一但有选中组的展开就会触发setOnCheckedChangeListener,而且选中状态就会混乱,而且混乱的乱七八糟。

综上所述:Expandablelistview+CheckBox最好不要用setOnCheckedChangeListener

你可能感兴趣的:(Expandablelistview与CheckBox+setOnCheckedChangeListener有坑)