今天公司有一个需求是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
//item.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_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="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>
<?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>