今天公司有一个需求是ExpandableListView包含复选操作,应为没有做过双层的复选所以写一篇博客,希望对看到的人有所启发其中有队ChecxBox添加标记防止ChecxBox选择错位,对这块不了解的可以看一下我的当ListView的item为CheckBox,EditText,Spinner的时候处理滑动数据错乱这篇文章。
那么先来看看MainActivity的代码
public class MainActivity extends AppCompatActivity {
//适配器
private ExpandableAdapter adapter;
@BindView(R.id.mListView)
ExpandableListView mListView;
//数据源
private List<ParentInfo> lists=new ArrayList<ParentInfo>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
init();
//引用
adapter=new ExpandableAdapter(this,lists);
mListView.setAdapter(adapter);
}
//初始化数据
private void init(){
for(int i=0;i<10;i++){
ParentInfo po=new ParentInfo();
ArrayList<ChildInfo> list=new ArrayList<ChildInfo>();
po.setTitle("哈哈"+i);
for (int j = 0; j <5; j++) {
ChildInfo chd=new ChildInfo();
chd.setTitle("呵呵"+j);
list.add(chd);
}
po.setChildList(list);
lists.add(po);
}
}
}
可以看到在MainActivity中我们的代码是很少的主要的代码都在ExpandableAdapter中
package com.demo;import java.util.ArrayList;import java.util.List;import com.ypy.eventbus.EventBus;import android.content.Context;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseExpandableListAdapter;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.CompoundButton.OnCheckedChangeListener;import android.widget.TextView;public class ExpandableAdapter extends BaseExpandableListAdapter {
private Context context;
private List<TestInfo> list;
private boolean isAll=false;
public ExpandableAdapter(Context context, List<TestInfo> list) {
super();
this.context = context;
this.list = list;
}
public List<TestInfo> getList() {
return list;
}
public ExpandableAdapter() {
super();
}
@Override
public int getGroupCount() {
return list.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return list.get(groupPosition).getChild().size();
}
@Override
public Object getGroup(int groupPosition) {
return list.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return list.get(groupPosition).getChild().get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return 0;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
@Override
public boolean hasStableIds() {
return false;
}
ViewHolder vh;
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View v, ViewGroup parent) {
if(v==null){
v=LayoutInflater.from(context).inflate(R.layout.item, null,false);
vh=new ViewHolder(v);
vh.chx_parent.setOnCheckedChangeListener(new MyParentCheckedChangeListener(vh.chx_parent));
v.setTag(vh);
}else{
vh=(ViewHolder) v.getTag();
}
TestInfo ts=list.get(groupPosition);
vh.chx_parent.setFocusable(false);
vh.tv_parent.setText(ts.getTitle());
vh.chx_parent.setTag(groupPosition);
vh.chx_parent.setChecked(ts.isChecx());
return v;
}
class MyParentCheckedChangeListener implements OnCheckedChangeListener{
CheckBox check;
public MyParentCheckedChangeListener() {
super();
}
public MyParentCheckedChangeListener(CheckBox check) {
super();
this.check = check;
}
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
int index=(Integer) check.getTag();
TestInfo test=list.get(index);
ArrayList<ChildInfo> child=test.getChild();
int size=child.size();
boolean ischex=false;
if(isChecked){
for (int i = 0; i<size; i++) {
child.get(i).setChecx(true);
}
test.setChecx(isChecked);
}else{
for (int i = 0; i<size; i++) {
if(child.get(i).isChecx()){
ischex=true;
}else{
ischex=false;
break;
}
}
if(ischex){
for (int i = 0; i<size; i++) {
child.get(i).setChecx(false);
}
test.setChecx(false);
}else{
test.setChecx(false);
}
}
init();
EventBus.getDefault().post(new RefreshEvent(isAll));
notifyDataSetChanged();
}
}
ViewHolder2 vh2;
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View v, ViewGroup parent) {
if(v==null){
v=LayoutInflater.from(context).inflate(R.layout.item_child, null,false);
vh2=new ViewHolder2(v);
vh2.chx_child.setOnCheckedChangeListener(new MyChildCheckedChangeListener(vh2.chx_child));
v.setTag(vh2);
}else{
vh2=(ViewHolder2) v.getTag();
}
TestInfo ts=list.get(groupPosition);
ArrayList<ChildInfo> titls=ts.getChild();
vh2.chx_child.setFocusable(false);
Bundle bund=new Bundle();
bund.putInt("parent", groupPosition);
bund.putInt("child", childPosition);
vh2.chx_child.setTag(bund);
vh2.tv_child.setText(titls.get(childPosition).getTitle());
vh2.chx_child.setChecked((titls.get(childPosition).isChecx()));
return v;
}
class MyChildCheckedChangeListener implements OnCheckedChangeListener{
CheckBox check;
public MyChildCheckedChangeListener() {
super();
}
public MyChildCheckedChangeListener(CheckBox check) {
super();
this.check = check;
}
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
Bundle bund=(Bundle) check.getTag();
int parent=bund.getInt("parent");
int child=bund.getInt("child");
TestInfo test=list.get(parent);
ArrayList<ChildInfo> childInfo=test.getChild();
ChildInfo co=childInfo.get(child);
co.setChecx(isChecked);
int size=childInfo.size();
boolean ischex=false;
for (int i = 0; i<size; i++) {
if(childInfo.get(i).isChecx()){
ischex=true;
}else{
ischex=false;
break;
}
}
test.setChecx(ischex);
init();
EventBus.getDefault().post(new RefreshEvent(isAll));
notifyDataSetChanged();
}
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
class ViewHolder{
private TextView tv_parent;
private CheckBox chx_parent;
public ViewHolder() {
super();
}
public ViewHolder(View v) {
tv_parent=(TextView) v.findViewById(R.id.tv_parent);
chx_parent=(CheckBox) v.findViewById(R.id.chx_parent);
}
}
class ViewHolder2{
private TextView tv_child;
private CheckBox chx_child;
public ViewHolder2() {
super();
}
public ViewHolder2(View v) {
tv_child=(TextView) v.findViewById(R.id.tv_child);
chx_child=(CheckBox) v.findViewById(R.id.chx_child);
}
}
private void init(){
for (int i = 0; i <10; i++) {
TestInfo tt=new TestInfo();
if(tt.isChecx()){
isAll=true;
}else{
isAll=false;
break;
}
ArrayList<ChildInfo> list=tt.getChild();
for (int j = 0; j <5; j++) {
ChildInfo childInfo=list.get(i);
if(childInfo.isChecx()){
isAll=true;
}else{
isAll=false;
break;
}
}
if(isAll==false){
break;
}
}
}}
通过实体bean来判断是否选中
public class ChildInfo implements Serializable {
//子项标题
private String title;
//子项是否被选中
private boolean isCheck;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public boolean isCheck() {
return isCheck;
}
public void setCheck(boolean check) {
isCheck = check;
}
}
package com.kotlintest;
import java.io.Serializable;
import java.util.ArrayList;
/**
* Created by liuqiang on 2017/4/25.
*/
public class ParentInfo implements Serializable{
//父级标题
private String title;
//对应的一个或多个子项
private ArrayList<ChildInfo> childList;
//父级是否选中
private boolean isChecx;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public ArrayList<ChildInfo> getChildList() {
return childList;
}
public void setChildList(ArrayList<ChildInfo> childList) {
this.childList = childList;
}
public boolean isChecx() {
return isChecx;
}
public void setChecx(boolean checx) {
isChecx = checx;
}
}
最后在附上我的布局文件
//activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context="com.kotlintest.MainActivity">
<ExpandableListView
android:id="@+id/mListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
>
</ExpandableListView>
</android.support.constraint.ConstraintLayout>
//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="match_parent">
<android.support.v7.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginRight="30dp"
android:layout_marginTop="10dp"
android:orientation="horizontal"
>
<TextView
android:id="@+id/tv_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16dp"
android:layout_weight="9" />
<CheckBox
android:id="@+id/chx_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
</android.support.v7.widget.LinearLayoutCompat>
</LinearLayout>
//item_chil.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="match_parent">
<android.support.v7.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:orientation="horizontal"
>
<TextView
android:id="@+id/tv_child"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16dp"
android:layout_weight="9" />
<CheckBox
android:id="@+id/chx_child"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
</android.support.v7.widget.LinearLayoutCompat>
</LinearLayout>