效果图
1.引入控件
<com.example.rockcloud.view.CustomExpandableListView
android:id="@+id/expandListView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.example.rockcloud.view.CustomExpandableListView>
2.继承控件,重写measure方法,应对原始控件显示不全问题。
public class CustomExpandableListView extends ExpandableListView {
public CustomExpandableListView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public CustomExpandableListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public CustomExpandableListView(Context context, AttributeSet attrs,int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >>2 ,MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
3.循环树的数据源实体类(列表分支过多的不建议使用list变量)
public class DataTree implements Serializable {
//直系父级名称
private String name;
//直系子集列表
private List<String> list;
//继承上类子集列表
private List<DataTree> dataTreeList;
//二级数据源
public DataTree(String name, List<String> list) {
this.name = name;
this.list = list;
}
//N级数据源
public DataTree(String name, List<String> list, List<DataTree> dataTreeList) {
this.name = name;
this.list = list;
this.dataTreeList = dataTreeList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public List<DataTree> getDataTreeList() {
return dataTreeList;
}
public void setDataTreeList(List<DataTree> dataTreeList) {
this.dataTreeList = dataTreeList;
}
}
4.定义继承于BaseExpandableListAdapter的适配器进行数据循环。
public class ExpandListViewTreeAdapter extends BaseExpandableListAdapter {
private List <DataTree> dataTreeList;
private Context context;
public ExpandListViewTreeAdapter(List <DataTree> dataTreeList,Context context){
this.dataTreeList=dataTreeList;
this.context=context;
}
/**
* 恒定返回父节点个数
* @return
*/
@Override
public int getGroupCount() {
return dataTreeList.size();
}
/**
* @param groupPosition 当前父节点位置
*
* @return 当使用多级嵌套时,这个数值要返回1,要不然本级子节点个数==本级节点个数*下级子节点个数;(数据重复)
*/
@Override
public int getChildrenCount(int groupPosition) {
if(dataTreeList.get(groupPosition).getDataTreeList()==null)
{
return dataTreeList.get(groupPosition).getList().size();
}
else{
return 1;
}
}
/**
* @param groupPosition
* @return 父节点名称;
*/
@Override
public Object getGroup(int groupPosition) {
return dataTreeList.get(groupPosition).getName();
}
/**
*
* @param groupPosition
* @param childPosition
* @return 子节点名称;
*/
@Override
public Object getChild(int groupPosition, int childPosition) {
return dataTreeList.get(groupPosition).getList().get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
return generateTextView(dataTreeList.get(groupPosition).getName());
}
/**
* @param groupPosition
* @param childPosition
* @param isLastChild
* @param convertView
* @param parent
* @return 当数据下级DataList不为空时,意味着有双重节点,传递下级DataList,返回ExpandListView。为空时说明这是最后一个节点,遍历List<String>list,返回TextView;
*/
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
if(dataTreeList.get(groupPosition).getDataTreeList()==null){
return generateTextView(dataTreeList.get(groupPosition).getList().get(childPosition));
}else {
return generateExpandableListView(dataTreeList.get(groupPosition).getDataTreeList());
}
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
/**
* @param dataTreeList
* @return 动态生成ExpandableListView;
*/
private ExpandableListView generateExpandableListView(List <DataTree> dataTreeList){
CustomExpandableListView view = new CustomExpandableListView(context);
ExpandListViewTreeAdapter adapter = new ExpandListViewTreeAdapter(dataTreeList,context);
view.setAdapter(adapter);
view.setPadding(20,0,0,0);
return view;
}
/**
* @param name
* @return 动态生成TextView;
*/
private TextView generateTextView(String name){
AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
TextView textView = new TextView(context);
textView.setLayoutParams(layoutParams);
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
textView.setTextSize(20);
textView.setPadding(100, 20, 0, 20);
textView.setText(name);
textView.setTextColor(Color.BLACK);
return textView;
}
}
5.动态使用
ExpandListViewTreeAdapter adapter = new ExpandListViewTreeAdapter(firstNames, getContext());
binding.expandListView.setAdapter(adapter);
原始数据
List <String> list=new ArrayList<>();
list.add("707");
list.add("808");
List<DataTree> list1=new ArrayList<>();
list1.add(new DataTree("第一层",list));
list1.add(new DataTree("第二层",list));
firstNames=new ArrayList<>();
List <DataTree>dataTreeList=new ArrayList<>();
dataTreeList.add(new DataTree("七号楼",list,list1));
List <DataTree> dataTreeList1=new ArrayList<>();
List <DataTree> dataTreeList2=new ArrayList<>();
dataTreeList2.add(new DataTree("家里蹲大学",new ArrayList<>(),dataTreeList));
firstNames.add(new DataTree("天津市",new ArrayList<>(),dataTreeList2));