Android开发:UI组件:ExpandableListView

  前言:感觉自己在大学里学习android已经到了一个瓶颈,总觉得无法突破,思来想去觉得还是基础打的不够牢固,所以我决定在博客中把我学过的知识和新学的知识做一个总结,我将会好好地研究我写出的每一行代码,打牢自己的基础。

  最近在完善自己程序的时候发现一个新的组件,用于列表的开合,例如qq好友的列表。今天在这做一个总结。话不多说直接开始!

  先做我们的布局文件

  • main布局文件中写入组件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
	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"
    tools:context="Learn_Tedu.UI.ExpandableListText">
    
    <ExpandableListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/expandablelist_1"
    />

</androidx.constraintlayout.widget.ConstraintLayout>
  • 父布局xml文件,这个是用来展现一级列表,负责点击展开与隐藏,这里可以根据自己需求自定义布局,包括下面要讲到的子布局xml文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/able_expandable_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="父布局测试"
        android:textSize="30sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
  • 子布局xml文件,用于二级列表:展开的列表;可根据自己需求自定义
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/able_expandable_child_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="子布局测试"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

ok,开始我们的代码部分

  • 创建资源
public class ExpandableListText extends AppCompatActivity {
//    列表框
    ExpandableListView listView;
//    父布局资源
    String[] parentValues = {"第一个父列表","第二个父列表","第三个父列表"};
//    子布局资源
    String[][] childValues = {
            {"第一列表中的第一子列表","第一列表中的第二子列表","第一列表中的第三子列表"},
            {"第二列表中的第一子列表","第二列表中的第二子列表"},
            {"第三列表中的第一子列表"}};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_expandable_list_text);
        setView();
    }

    /**
     * 初始化布局文件
     */
    private void setView() {
        listView = findViewById(R.id.expandablelist_1);
//        设置适配器
        listView.setAdapter(new MyAdapter());
    }
}
  • 构造适配器
/**
      /**
     * ExpandablelistView专用适配器
     */
    class MyAdapter extends BaseExpandableListAdapter {
        /**
         * 获取父列表大小
         * @return 大小
         */
        @Override
        public int getGroupCount() {
            return parentValues.length;
        }

        /**
         * 指定父布局下的子布局大小
         * @param groupPosition 父布局下标
         * @return 子布局大小
         */
        @Override
        public int getChildrenCount(int groupPosition) {
            return childValues[groupPosition].length;
        }

        /**
         * 加载父布局资源
         * @param groupPosition 父布局下标
         * @return 要设置的资源
         */
        @Override
        public Object getGroup(int groupPosition) {
            return parentValues[groupPosition];
        }

        /**
         * 加载子布局资源
         * @param groupPosition 父布局下标
         * @param childPosition  子布局下标
         * @return 要设置的资源
         */
        @Override
        public Object getChild(int groupPosition, int childPosition) {
            return childValues[groupPosition][childPosition];
        }

        /**
         * 获取父布局的id
         * @param groupPosition 父布局下标
         * @return 父布局id
         */
        @Override
        public long getGroupId(int groupPosition) {
            return groupPosition;
        }

        /**
         * 获取子布局的id
         * @param groupPosition 父布局id
         * @param childPosition 子布局id
         * @return 子布局id
         */
        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return childPosition;
        }

        /**
         * //分组和子选项是否持有稳定的ID,
         * @return 是否稳定
         */
        @Override
        public boolean hasStableIds() {
            return true;
        }

        /**
         * 加载父布局视图
         * @param groupPosition 父布局下标
         * @param isExpanded 是否是展开状态
         * @param convertView 重用已有的视图对象
         * @param parent 视图组
         * @return 父布局界面
         */
        @Override
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
            MyGroupHolder groupHolder;
            if (convertView == null){
                convertView = LayoutInflater.from(ExpandableListText.this).inflate(R.layout.able_expandable_parent,parent,
                        false);
                groupHolder = new MyGroupHolder(convertView);
                convertView.setTag(groupHolder);
            } else {
               groupHolder = (MyGroupHolder) convertView.getTag();
            }
            groupHolder.textView.setText(parentValues[groupPosition]);
            return convertView;
        }

        /**
         * 加载子布局文件
         * @param groupPosition 父布局下标
         * @param childPosition 子布局下标
         * @param isLastChild 该子项是否为组中的最后一个子项
         * @param convertView 重用已有的视图对象
         * @param parent 视图组
         * @return 子布局文件
         */
        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
            MyChildHolder childHolder;
            if (convertView == null){
                convertView = LayoutInflater.from(ExpandableListText.this).inflate(
                        R.layout.able_expandable_child,parent,false);
                childHolder = new MyChildHolder(convertView);
                convertView.setTag(childHolder);
            }else{
                childHolder = (MyChildHolder) convertView.getTag();
            }
            childHolder.textView.setText(childValues[groupPosition][childPosition]);
            return convertView;
        }

        /**
         * 指定的子列表是否可点击
         * @param groupPosition 父布局下标
         * @param childPosition 子布局下标
         * @return 是否可点击
         */
        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }
    }

    static class MyGroupHolder {
        TextView textView;
        MyGroupHolder(View view){
            textView = view.findViewById(R.id.able_expandable_text);
        };
    }

    static class MyChildHolder{
        TextView textView;
        MyChildHolder(View view){
            textView = view.findViewById(R.id.able_expandable_child_text);
        }
    }
  • 设置列表及监听事件
   /**
     * 设置展开列表
     */
    private void setExpandable() {
//        默认打开或关闭所有列表
        for (int i = 0; i < parentValues.length; i++){
            listView.expandGroup(i);//打开指定列表
            listView.collapseGroup(i);//关闭指定列表
        }
        //父列表点击事件
        listView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            /**
             *
             * @param parent 点击的父组件
             * @param v 点击的视图
             * @param groupPosition 坐标
             * @param id id
             * @return 是否拦截
             */
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                Log.d(TAG, "onGroupClick: 父列表被点击");
                return false;
            }
        });
        //父列表展开
        listView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
            @Override
            public void onGroupExpand(int groupPosition) {
                Log.d(TAG, "onGroupExpand: 父列表展开" + groupPosition);
            }
        });
        //父列表关闭
        listView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
            @Override
            public void onGroupCollapse(int groupPosition) {
                Log.d(TAG, "onGroupCollapse: 父列表关闭" + groupPosition);
            }
        });
        //子列表点击
        listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
                Log.d(TAG, "onChildClick: 字列表点击");
                return false;
            }
        });
    }

对于ExpandableListview大概的功能就介绍到这里了,这些都是作者亲自实验过的,有什么问题和错误可以到评论区补充

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值