这段时间在项目中遇到了二级标签列表的实现,可是项目中的代码用的是人家第三方的,所以我决定用ExpandableListView来实现二级标签列表(这个demo上周就写好了,因为上周找房子没更博,难受啊,贵的房子租不起,便宜的房子要不然太小,要不然环境差…努力提高自己吧,等工资提上来了,一切都好说)扯远了,让我们上一下效果图:

android 一级折叠列表 android 二级折叠列表_android

首先说一下什么是ExpandableListView,ExpandableListView继承ListView,一种比较常见的一个比较简单的实现二级标签列表的控件。为了实现上面的效果图,我们所要做的如下:
一:创建数据源类(我按照一般后台接口返回的数据格式建类)

public class BeanFirstItemBase {
    private String name;
    private List<BeanSecondItem> beanSecondItem;

    public List<BeanSecondItem> getBeanSecondItem() {
        return beanSecondItem;
    }
    public void setBeanSecondItem(List<BeanSecondItem> beanSecondItem) {
        this.beanSecondItem = beanSecondItem;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    static class BeanSecondItem {//二级标签类
        private String name;
        public BeanSecondItem(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
}

二.布局文件
1.activity_expand_view(activity布局文件)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".activity.expandlistview.ExpandListViewActivity">
    <ExpandableListView
        android:id="@+id/el_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         />
</LinearLayout>

2.item_first_label(一级标签列表布局)
大家看这个布局文件LinearLayout里面又包了一层LinearLayout,可能认为多余,其实不是这样,要想自定义一级标签列表的宽度,必须里面在包一层布局,这是什么原因,当时我也问了几个人,他们也没回答出来,这个如果有人知道可以告诉我一下~~,下面二级标签列表布局也一样(其中icon_huanzhe_xiala1图片我没给出来,这就是表示以及标签列表是展开还是关闭的图片显示,大家可以网上找一下)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tool="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:textSize="18sp"
            tool:text="333" />

        <ImageView
            android:id="@+id/iv_state"
            android:layout_width="15dp"
            android:layout_height="15dp"
            android:layout_marginRight="25dp"
            android:src="@mipmap/icon_huanzhe_xiala1" />
    </LinearLayout>
</LinearLayout>

3.item_second_label(二级标签布局)

<?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="wrap_content"
    android:gravity="center_vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_child_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:gravity="center_vertical"
            android:text="333"
            android:textColor="#008577"
            android:textSize="18sp" />
    </LinearLayout>
</LinearLayout>

三.自定义适配器ExpandListViewAdapter

public class ExpandListViewAdapter extends BaseExpandableListAdapter {

    private List<BeanFirstItemBase> mFirstItemList;//从Activity传过来的数据源
    private Context mContext;

    public ExpandListViewAdapter(List<BeanFirstItemBase> mFirstItemList, Context mContext) {
        this.mFirstItemList = mFirstItemList;
        this.mContext = mContext;
    }

    //返回的是一级标签的数量
    @Override
    public int getGroupCount() {
        return mFirstItemList.size();
    }

    //返回的是子标签的数量
    @Override
    public int getChildrenCount(int groupPosition) {
        return mFirstItemList.get(groupPosition).getBeanSecondItem().size();
    }

    //获得某个一级标签的内容
    @Override
    public Object getGroup(int groupPosition) {
        return mFirstItemList.get(groupPosition);
    }

    //获得某个一级标签下的子标签
    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return mFirstItemList.get(groupPosition).getBeanSecondItem().get(childPosition);
    }

    //一级标签列表的Id
    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    //二级标签列表的Id
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    //具体啥作用,真不清楚~~
    @Override
    public boolean hasStableIds() {
        return true;
    }

    //显示一级标签列表
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        FirstViewHolder firstViewHolder;
        if (convertView == null) {//第一次展示View 没有被创建
            convertView = LayoutInflater.from(mContext).inflate(R.layout.item_first_label, null);
            firstViewHolder = new FirstViewHolder(convertView);
            convertView.setTag(firstViewHolder);//创建之后,将firstViewHolder存到视图中
        } else {
            firstViewHolder = (FirstViewHolder) convertView.getTag();//将firstViewHolder 拿出来
        }
        firstViewHolder.tvName.setText(mFirstItemList.get(groupPosition).getName());//赋值
        if (isExpanded) {//表明此时已经展开
            firstViewHolder.ivState.setImageDrawable(mContext.getResources().getDrawable(R.mipmap.icon_huanzhe_xiala3));
            //这个图我没有给,就是表示一级标签列表展开的图标,因为不好发图,网上找一下就行了,具体可以看动图,下面也是
        } else {//表明此时已经关闭
            firstViewHolder.ivState.setImageDrawable(mContext.getResources().getDrawable(R.mipmap.icon_huanzhe_xiala1));
        }
        return convertView;
    }

    //显示二级标签列表
    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        SecondViewHolder secondViewHolder;
        if (convertView == null) {//第一次展示View 没有被创建
            convertView = LayoutInflater.from(mContext).inflate(R.layout.item_second_label, null);
            secondViewHolder = new SecondViewHolder(convertView);
            convertView.setTag(secondViewHolder);//创建之后,将firstViewHolder存到View中
        } else {
            secondViewHolder = (SecondViewHolder) convertView.getTag();//将firstViewHolder从View拿出来
        }
        secondViewHolder.tvChildName.setText(mFirstItemList.get(groupPosition).getBeanSecondItem().get(childPosition).getName());

        return convertView;
    }

    //指定位置上的child能否被选中
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
       /* 下面我注释掉方法的表示当二级标签名为张三  不响应点击事件  有兴趣可以试一下
                if (mFirstItemList.get(groupPosition).getBeanSecondItem().get(childPosition).getName().equals("张三")) {
            return false;
        } else {
            return true;
        }*/
        return true;
    }

    static class FirstViewHolder {
        TextView tvName;
        ImageView ivState;

        FirstViewHolder(View view) {
            tvName = view.findViewById(R.id.tv_name);
            ivState = view.findViewById(R.id.iv_state);
        }
    }

    static class SecondViewHolder {

        TextView tvChildName;

        SecondViewHolder(View view) {

            tvChildName = view.findViewById(R.id.tv_child_name);
        }
    }
}

四:ExpandListViewActivity的书写

public class ExpandListViewActivity extends AppCompatActivity {

    @BindView(R.id.el_list)
    ExpandableListView mElList;


    private List<BeanFirstItemBase> mBeanFirstItemBases = new ArrayList<>();//数据源
    private ExpandableListAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_expand_view);
        ButterKnife.bind(this);
        initView();
    }

    private void initView() {

        //初始化数据
        BeanFirstItemBase beanFirstItemBase1 = new BeanFirstItemBase();
        beanFirstItemBase1.setName("第一组");
        List<BeanFirstItemBase.BeanSecondItem> beanSecondItems1 = new ArrayList<>();
        //BeanFirstItemBase.BeanSecondItem b=new BeanFirstItemBase.BeanSecondItem("张三");
        beanSecondItems1.add(new BeanFirstItemBase.BeanSecondItem("张三"));
        beanSecondItems1.add(new BeanFirstItemBase.BeanSecondItem("李四"));
        beanSecondItems1.add(new BeanFirstItemBase.BeanSecondItem("王五"));
        beanFirstItemBase1.setBeanSecondItem(beanSecondItems1);


        BeanFirstItemBase beanFirstItemBase2 = new BeanFirstItemBase();
        beanFirstItemBase2.setName("第二组");
        List<BeanFirstItemBase.BeanSecondItem> beanSecondItems2 = new ArrayList<>();
        beanSecondItems2.add(new BeanFirstItemBase.BeanSecondItem("赵六"));
        beanSecondItems2.add(new BeanFirstItemBase.BeanSecondItem("孙七"));
        beanSecondItems2.add(new BeanFirstItemBase.BeanSecondItem("周八"));
        beanFirstItemBase2.setBeanSecondItem(beanSecondItems2);

        BeanFirstItemBase beanFirstItemBase3 = new BeanFirstItemBase();
        beanFirstItemBase3.setName("第三组");
        List<BeanFirstItemBase.BeanSecondItem> beanSecondItems3 = new ArrayList<>();
        beanSecondItems3.add(new BeanFirstItemBase.BeanSecondItem("吴九"));
        beanSecondItems3.add(new BeanFirstItemBase.BeanSecondItem("郑十"));
        beanFirstItemBase3.setBeanSecondItem(beanSecondItems3);

        mBeanFirstItemBases.add(beanFirstItemBase1);
        mBeanFirstItemBases.add(beanFirstItemBase2);
        mBeanFirstItemBases.add(beanFirstItemBase3);

        //上面一系列都是为了获得数据源  都是为了获得数据源


        mAdapter = new ExpandListViewAdapter(mBeanFirstItemBases, ExpandListViewActivity.this);//将数据源传到Adapter中
        mElList.setGroupIndicator(null);//去掉默认左边的图标
        mElList.setAdapter(mAdapter);


        //二级标签列表的点击事件
        mElList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {

                Toast.makeText(ExpandListViewActivity.this, mBeanFirstItemBases.get(groupPosition).getBeanSecondItem().get(childPosition).getName(), Toast.LENGTH_SHORT).show();
                return true;
            }
        });
    }
}

总结:代码看着有点多,其实很简单,自己写个小demo就清楚了。