ExpandableListView可扩展列表视图,可折叠列表视图

目录

1. XML代码

2. ExpandableListView的使用

3. ExpandableListAdapter的使用

4. 数据观察者的使用

5. 案例代码一览


ExpandableListView(可扩展/可折叠列表视图)是一种多功能的高级控件,每个子项都可以展开一个孙子列表。点击一个分组(子项),即可展开该分组下的孙子列表;再次点击该分组,即可收起该分组下的孙子项列表。

1. XML代码

<ExpandableListView
    android:id="@+id/expandableListView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

2. ExpandableListView的使用

可折叠列表视图的常用方法说明:

  • setAdapter:设置适配器。适配器类型为ExpandableListAdapter。
  • expandGroup:展开指定分组。
  • collapseGroup:收起指定分组。
  • isGroupExpanded:判断指定分组是否展开。
  • setSelectedGroup:设置选中的分组。
  • setSelectedChild:设置选中的孙子项。
  • setGroupIndicator:设置指定分组的指示图像。
  • setChildIndicator:设置指定孙子项的指示图像。
  • setOnGroupExpandListener:设置分组展开监听器。需实现接口 OnGroupExpandListener的onGroupExpand方法,该方法在点击展开分组时触发。
  • setOnGroupCollapseListener:设置分组收起监听器。需实现接口 OnGroupCollapseListener的onGroupCollapse方法,该方法在点击收起分组时触发。
  • setOnGroupClickListener:设置分组点击监听器。需实现接口 OnGroupClickListener 的onGroupClick方法,该方法在点击分组时触发。
  • setOnChildClickListener:设置孙子项点击监听器。需实现接口 OnChildClickListener 的onChildClick方法,该方法在点击孙子项时触发。

3. ExpandableListAdapter的使用

可折叠列表视图拥有专属的适配器ExpandableListAdapter(可折叠列表适配器)。

下面是该适配器经常要重写的5个方法:

  • getGroupCount:获取分组的个数。
  • getChildrenCount:获取孙子项的个数。
  • getGroupView:获取指定分组的视图。
  • getChildView:获取指定孙子项的视图。
  • isChildSelectable:判断孙子项是否允许选择。

全部方法使用说明如下所示:

class MyAdapter implements ExpandableListAdapter {
    DataSetObserver dataSetObserver;
    public MyAdapter(){
        //构造方法,可以在参数中进行数据传入
    }
    //注册数据观察者
    public void registerDataSetObserver(DataSetObserver dataSetObserver) {
        this.dataSetObserver=dataSetObserver;
    }
    //注销数据观察者
    public void unregisterDataSetObserver(DataSetObserver dataSetObserver) {
        dataSetObserver=null;
    }
    //返回父项的数量,即可展开列表中的组数
    public int getGroupCount() {
        return 0;
    }
    //返回特定组(父项)中子项的数量
    public int getChildrenCount(int i) {
        return 0;
    }
    //返回指定位置的父项对象
    public Object getGroup(int i) {
        return null;
    }
    //返回指定位置的子项对象
    public Object getChild(int i, int i1) {
        return null;
    }
    //返回指定位置的父项的唯一标识符
    public long getGroupId(int i) {
        return 0;
    }
    //返回指定位置的子项的唯一标识符
    public long getChildId(int i, int i1) {
        return 0;
    }
    //返回一个布尔值,表示适配器的项目是否具有稳定的唯一标识符。如果返回 true,则表示每个项的标识符在数据集的生命周期内保持稳定
    public boolean hasStableIds() {
        return false;
    }
    //获取父项的视图
    public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
        return null;
    }
    //获取子项的视图
    public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
        return null;
    }
    //返回一个布尔值,表示特定的子项是否可选
    public boolean isChildSelectable(int i, int i1) {
        return false;
    }
    //返回一个布尔值,表示所有的列表项是否可选。一般情况下,如果所有项都是可选的,则返回 true
    public boolean areAllItemsEnabled() {
        return false;
    }
    //返回一个布尔值,表示适配器是否为空。
    public boolean isEmpty() {
        return false;
    }
    //在父项展开时被调用
    public void onGroupExpanded(int i) {

    }
    //在父项折叠时被调用
    public void onGroupCollapsed(int i) {

    }
    //用于获取子项的组合ID。这在某些情况下可以用于唯一标识某个项。
    public long getCombinedChildId(long l, long l1) {
        return 0;
    }
    //用于获取父项的组合ID。这在某些情况下可以用于唯一标识某个项。
    public long getCombinedGroupId(long l) {
        return 0;
    }
}

4. 数据观察者的使用

在Android中,要让DataSetObserver(数据观察者)监听数据,通常需要将它注册到适配器(Adapter)或者数据集(DataSet)上。然后,当数据集的内容发生变化时,DataSetObserver中相应的方法会被自动调用。

//获取控件
ExpandableListView expandableListView=findViewById(R.id.expandableListView);

//创建适配器
MyAdapter myAdapter=new MyAdapter();

//创建数据观察者
DataSetObserver dataSetObserver=new DataSetObserver() {
    public void onChanged() {
        super.onChanged();
        //数据变化时修改UI
    }
    public void onInvalidated() {
        super.onInvalidated();
        //数据集无效时调用此方法
    }
};

//注册数据观察者
myAdapter.registerDataSetObserver(dataSetObserver);
//设置适配器
expandableListView.setAdapter(myAdapter);

//...数据变化...
//使用数据观察者,调用onChanged方法
myAdapter.dataSetObserver.onChanged();

5. 案例代码一览

<!--activity_main_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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ExpandableListView
            android:id="@+id/expandableListView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!--group_layout.xml-->

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/teal_200">
    <TextView
        android:id="@+id/group_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="group-null"/>
</RelativeLayout>
<!--child_layout.xml-->

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:background="@color/purple_700">
    <TextView
        android:id="@+id/child_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="child-null"/>
</RelativeLayout>
//自定义适配器

class MyAdapter implements ExpandableListAdapter {
    ArrayList<View> groupArrayList=null;
    ArrayList<ArrayList<View>> childArrayLists=null;
    public MyAdapter(ArrayList<View> groupArrayList,ArrayList<ArrayList<View>> childArrayLists){
        //构造方法,可以在参数中进行数据传入
        this.groupArrayList=groupArrayList;
        this.childArrayLists=childArrayLists;
    }
    //返回父项的数量,即可展开列表中的组数
    public int getGroupCount() {
        return groupArrayList.size();
    }
    //返回特定组(父项)中子项的数量
    public int getChildrenCount(int i) {
        return childArrayLists.get(i).size();
    }
    //获取父项的视图
    public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
        return groupArrayList.get(i);
    }
    //获取子项的视图
    public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
        return childArrayLists.get(i).get(i1);
    }
    //返回一个布尔值,表示特定的子项是否可选
    public boolean isChildSelectable(int i, int i1) {
        return false;
    }
    
    //...其他方法
}
//MainActivity.java

public class MainActivity extends AppCompatActivity {
    @SuppressLint("MissingInflatedId")
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //准备参数
        ArrayList<View> groupArrayList=new ArrayList<>();
        ArrayList<ArrayList<View>> childArrayLists=new ArrayList<>();
        for(int i=0;i<10;i++){
            //group
            View view= LayoutInflater.from(MainActivity.this).inflate(R.layout.group_layout,null);
            ((TextView)view.findViewById(R.id.group_textView)).setText("group:"+i);
            groupArrayList.add(view);
            //child
            ArrayList<View> childArrayList=new ArrayList<>();
            for(int i1=0;i1<6;i1++){
                View view1=LayoutInflater.from(MainActivity.this).inflate(R.layout.child_layout,null);
                ((TextView)view1.findViewById(R.id.child_textView)).setText("child:"+i1);
                childArrayList.add(view1);
            }
            childArrayLists.add(childArrayList);
        }

        //获取控件
        ExpandableListView expandableListView=findViewById(R.id.expandableListView);

        //创建适配器
        MyAdapter myAdapter=new MyAdapter(groupArrayList,childArrayLists);
        //设置适配器
        expandableListView.setAdapter(myAdapter);
    }
}

tag:ExpandableListView;可扩展列表视图;可折叠列表视图;适配器;Adapter

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用ExpandableListView可以实现QQ好友分组列表。首先需要创建一个ExpandableListView控件,并为其设置适配器。适配器需要继承BaseExpandableListAdapter,并实现以下方法: 1. getGroupCount():获取分组的数量。 2. getChildrenCount():获取某个分组下子项的数量。 3. getGroup():获取某个分组的数据。 4. getChild():获取某个分组下某个子项的数据。 5. getGroupId():获取某个分组的ID。 6. getChildId():获取某个分组下某个子项的ID。 7. hasStableIds():判断分组和子项的ID是否稳定。 8. getGroupView():获取分组的视图。 9. getChildView():获取子项的视图。 10. isChildSelectable():判断子项是否可选中。 在实现适配器的过程中,需要根据数据源的结构来设置分组和子项的数据。例如,可以使用一个List<List<String>>来存储分组和子项的数据,其中外层List表示分组,内层List表示子项。在getGroup()和getChild()方法中,需要根据groupPosition和childPosition来获取对应的数据。 最后,需要为ExpandableListView设置分组的展开和收起事件。可以通过设置OnGroupClickListener和OnChildClickListener来实现。在OnGroupClickListener中,需要根据groupPosition来判断当前分组是否已经展开,如果已经展开则返回false,否则返回true。在OnChildClickListener中,可以根据childPosition来获取对应的数据,并进行相应的操作。 通过以上步骤,就可以实现一个简单的QQ好友分组列表

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在下嗷呜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值