广告位联系
返回顶部
分享到

Android ExpandableListView用法介绍

Android 来源:互联网 作者:佚名 发布时间:2025-02-07 18:08:52 人浏览
摘要

在 Android 开发中,列表展示是一种非常常见的交互形式。而 ExpandableListView 作为一种特殊的列表控件,它允许我们创建具有分组功能的列表,每个分组下还可以包含多个子项,并且分组可以展开

在 Android 开发中,列表展示是一种非常常见的交互形式。而 ExpandableListView 作为一种特殊的列表控件,它允许我们创建具有分组功能的列表,每个分组下还可以包含多个子项,并且分组可以展开和收缩,这大大增强了数据展示的灵活性和可读性。本文将详细介绍 ExpandableListView 的用法,从基本概念到具体实现,再到高级应用,帮助你全面掌握这一控件。

1. ExpandableListView 基本概念

ExpandableListView 继承自 ListView,是 Android 提供的一种可展开的列表视图。它主要由分组(Group)和子项(Child)两部分组成。每个分组可以包含多个子项,用户可以通过点击分组来展开或收缩其对应的子项列表。这种控件适用于需要对数据进行分类展示的场景,例如联系人列表按照字母分组、商品列表按照类别分组等。

2. 布局文件中添加 ExpandableListView

首先,我们需要在布局文件中添加 ExpandableListView 控件。以下是一个简单的示例:

1

2

3

4

5

6

7

8

9

10

<!-- activity_main.xml -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical">

    <ExpandableListView

        android:id="@+id/expandableListView"

        android:layout_width="match_parent"

        android:layout_height="match_parent" />

</LinearLayout>

在这个布局中,我们创建了一个垂直的线性布局,并在其中添加了一个 ExpandableListView,其宽度和高度都设置为 match_parent,以填充整个父布局。

3. 创建数据模型

为了展示分组和子项的数据,我们需要创建相应的数据模型类。假设我们要展示一个水果分类列表,每个分类下有不同的水果,我们可以创建如下的数据模型类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

// GroupModel.java

public class GroupModel {

    private String groupName;

    public GroupModel(String groupName) {

        this.groupName = groupName;

    }

    public String getGroupName() {

        return groupName;

    }

    public void setGroupName(String groupName) {

        this.groupName = groupName;

    }

}

// ChildModel.java

public class ChildModel {

    private String childName;

    public ChildModel(String childName) {

        this.childName = childName;

    }

    public String getChildName() {

        return childName;

    }

    public void setChildName(String childName) {

        this.childName = childName;

    }

}

GroupModel 类用于表示分组信息,包含一个分组名称;ChildModel 类用于表示子项信息,包含一个子项名称。

4. 创建适配器

ExpandableListView 需要使用适配器来将数据绑定到视图上。我们可以继承 BaseExpandableListAdapter 类来创建自定义适配器。以下是一个示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

import android.content.Context;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseExpandableListAdapter;

import android.widget.TextView;

import java.util.List;

public class MyExpandableListAdapter extends BaseExpandableListAdapter {

    private Context context;

    private List<GroupModel> groupList;

    private List<List<ChildModel>> childList;

    public MyExpandableListAdapter(Context context, List<GroupModel> groupList, List<List<ChildModel>> childList) {

        this.context = context;

        this.groupList = groupList;

        this.childList = childList;

    }

    @Override

    public int getGroupCount() {

        return groupList.size();

    }

    @Override

    public int getChildrenCount(int groupPosition) {

        return childList.get(groupPosition).size();

    }

    @Override

    public Object getGroup(int groupPosition) {

        return groupList.get(groupPosition);

    }

    @Override

    public Object getChild(int groupPosition, int childPosition) {

        return childList.get(groupPosition).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) {

        GroupModel groupModel = (GroupModel) getGroup(groupPosition);

        if (convertView == null) {

            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            convertView = inflater.inflate(android.R.layout.simple_expandable_list_item_1, null);

        }

        TextView groupTextView = convertView.findViewById(android.R.id.text1);

        groupTextView.setText(groupModel.getGroupName());

        return convertView;

    }

    @Override

    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {

        ChildModel childModel = (ChildModel) getChild(groupPosition, childPosition);

        if (convertView == null) {

            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            convertView = inflater.inflate(android.R.layout.simple_list_item_1, null);

        }

        TextView childTextView = convertView.findViewById(android.R.id.text1);

        childTextView.setText(childModel.getChildName());

        return convertView;

    }

    @Override

    public boolean isChildSelectable(int groupPosition, int childPosition) {

        return true;

    }

}

在这个适配器中,我们需要实现一系列的方法:

  • getGroupCount():返回分组的数量。
  • getChildrenCount(int groupPosition):返回指定分组下子项的数量。
  • getGroup(int groupPosition):返回指定位置的分组对象。
  • getChild(int groupPosition, int childPosition):返回指定分组下指定位置的子项对象。
  • getGroupId(int groupPosition) 和 getChildId(int groupPosition, int childPosition):分别返回分组和子项的 ID。
  • getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent):创建并返回分组的视图。
  • getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent):创建并返回子项的视图。
  • isChildSelectable(int groupPosition, int childPosition):指定子项是否可以被选中。

5. 在 Activity 中使用 ExpandableListView

在 Activity 中,我们需要初始化数据、创建适配器并将其设置给 ExpandableListView。以下是示例代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

import android.os.Bundle;

import android.widget.ExpandableListView;

import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ExpandableListView expandableListView;

    private MyExpandableListAdapter adapter;

    private List<GroupModel> groupList;

    private List<List<ChildModel>> childList;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        expandableListView = findViewById(R.id.expandableListView);

        // 初始化数据

        initData();

        // 创建适配器

        adapter = new MyExpandableListAdapter(this, groupList, childList);

        // 设置适配器

        expandableListView.setAdapter(adapter);

    }

    private void initData() {

        groupList = new ArrayList<>();

        childList = new ArrayList<>();

        // 添加分组数据

        GroupModel group1 = new GroupModel("热带水果");

        GroupModel group2 = new GroupModel("温带水果");

        groupList.add(group1);

        groupList.add(group2);

        // 为每个分组添加子项数据

        List<ChildModel> childList1 = new ArrayList<>();

        childList1.add(new ChildModel("香蕉"));

        childList1.add(new ChildModel("芒果"));

        childList.add(childList1);

        List<ChildModel> childList2 = new ArrayList<>();

        childList2.add(new ChildModel("苹果"));

        childList2.add(new ChildModel("梨"));

        childList.add(childList2);

    }

}

在 onCreate 方法中,我们首先获取 ExpandableListView 控件的引用,然后调用 initData 方法初始化数据,接着创建适配器并将其设置给 ExpandableListView。

6. 处理分组和子项的点击事件

我们可以为 ExpandableListView 添加分组和子项的点击事件监听器,以实现相应的交互逻辑。以下是示例代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

// 在 onCreate 方法中添加以下代码

expandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {

    @Override

    public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {

        // 处理分组点击事件

        GroupModel groupModel = (GroupModel) adapter.getGroup(groupPosition);

        String groupName = groupModel.getGroupName();

        // 这里可以添加自定义的逻辑,比如弹出提示框显示分组名称

        return false;

    }

});

expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {

    @Override

    public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {

        // 处理子项点击事件

        ChildModel childModel = (ChildModel) adapter.getChild(groupPosition, childPosition);

        String childName = childModel.getChildName();

        // 这里可以添加自定义的逻辑,比如跳转到详情页面

        return false;

    }

});

在分组点击事件监听器中,我们可以获取点击的分组对象并进行相应的处理;在子项点击事件监听器中,我们可以获取点击的子项对象并进行相应的处理。

7. 高级应用:自定义视图

除了使用系统提供的简单布局,我们还可以自定义分组和子项的视图,以实现更丰富的界面效果。以下是一个自定义视图的示例:
自定义分组布局文件 group_item.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:orientation="horizontal"

    android:padding="10dp">

    <ImageView

        android:id="@+id/group_icon"

        android:layout_width="24dp"

        android:layout_height="24dp"

        android:src="@mipmap/ic_launcher" />

    <TextView

        android:id="@+id/group_name"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_marginLeft="10dp"

        android:textSize="18sp" />

</LinearLayout>

自定义子项布局文件 child_item.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:orientation="horizontal"

    android:padding="10dp">

    <ImageView

        android:id="@+id/child_icon"

        android:layout_width="24dp"

        android:layout_height="24dp"

        android:src="@mipmap/ic_launcher" />

    <TextView

        android:id="@+id/child_name"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_marginLeft="10dp"

        android:textSize="16sp" />

</LinearLayout>

修改适配器中的 getGroupView 和 getChildView 方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

@Override

public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {

    GroupModel groupModel = (GroupModel) getGroup(groupPosition);

    if (convertView == null) {

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        convertView = inflater.inflate(R.layout.group_item, null);

    }

    ImageView groupIcon = convertView.findViewById(R.id.group_icon);

    TextView groupTextView = convertView.findViewById(R.id.group_name);

    groupTextView.setText(groupModel.getGroupName());

    return convertView;

}

@Override

public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {

    ChildModel childModel = (ChildModel) getChild(groupPosition, childPosition);

    if (convertView == null) {

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        convertView = inflater.inflate(R.layout.child_item, null);

    }

    ImageView childIcon = convertView.findViewById(R.id.child_icon);

    TextView childTextView = convertView.findViewById(R.id.child_name);

    childTextView.setText(childModel.getChildName());

    return convertView;

}

通过自定义视图,我们可以在分组和子项中添加更多的控件,如图片、按钮等,从而实现更复杂的界面效果。

8. 总结

ExpandableListView 是 Android 中一个非常实用的列表控件,它可以帮助我们实现具有分组功能的列表展示。通过本文的介绍,你应该已经掌握了 ExpandableListView 的基本用法,包括布局文件的添加、数据模型的创建、适配器的实现、点击事件的处理以及自定义视图的应用。在实际开发中,你可以根据具体需求对其进行进一步的扩展和优化,以满足不同的业务场景。希望本文对你有所帮助,祝你在 Android 开发中取得更好的成果!


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • Android ExpandableListView用法介绍
    在 Android 开发中,列表展示是一种非常常见的交互形式。而 ExpandableListView 作为一种特殊的列表控件,它允许我们创建具有分组功能的列表,
  • 基于Flutter实现扫描二维码功能

    基于Flutter实现扫描二维码功能
    在今天的移动开发中,二维码扫描已经成为了常见的功能之一。Flutter作为一款跨平台的开发框架,提供了丰富的插件和功能,使得开发者可
  • Android Service功能使用介绍
    在Android开发中,Service是一个在后台长时间运行的组件,不会提供用户界面。它可以用来处理一些需要在后台进行的操作,比如播放音乐、下
  • Android封装常用工具类的介绍
    日志封装类-MyLog 是对androidlog的封装,封装后 可以设置显示级别 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
  • Flutter web bridge通信总结分析介绍

    Flutter web bridge通信总结分析介绍
    公司医疗业务人手比较少【小而美】的团队~ 较少采用的前端技术架构是: toC:小程序 toB2C: Flutter + H5(SPA - React)【build ???????? Android + IOS】
  • Android Flutter自定义动画路由的介绍

    Android Flutter自定义动画路由的介绍
    flutter中有默认的Route组件,叫做MaterialPageRoute,一般情况下我们在flutter中进行跳转的话,只需要向Navigator中传入一个MaterialPageRoute就可以了。
  • Android实现获取短信验证码并自动填充

    Android实现获取短信验证码并自动填充
    最近弄了个短信自动填充功能,一开始觉得很简单,不就是动态注册个广播接收器去监听短信消息不就可以了吗?结果没这么简单,问题就
  • Android studio六大基本布局介绍
    Android中常用的布局方式有以下几种: 线性布局LinearLayout 相对布局RelativeLayout 表格布局TableLayout 层布局FrameLayout 绝对布局AbsoluteLayout 网格布
  • Android Service启动绑定流程介绍
    本文基于Android 11,参考《Android进阶解密》一书资料。了解Service的启动和绑定流程,以及Service的Context创建过程。 由于基于分析流程,忽略
  • Android自定义有限制区域的图例角度自识别涂鸦工

    Android自定义有限制区域的图例角度自识别涂鸦工
    上文Android:实现一个自定义有限制区域的图例(角度自识别)涂鸦工具类(中)中我们已经实现了在复杂的异形区域中涂鸦,最后生成图片
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计