• ExpandableListView使用


    相关博客
    ExpandableListView使用

    博客内容记录

    场景

    有时候,使用ListView并不能满足应用程序所需要的功能。有些应用程序需要多组ListView,这时候我们就要使用一种新的控件ExpandableListView——可以扩展的ListView。它的作用就是将ListView进行分组。就好像我们使用QQ的时候,有“我的好友”,“陌生人”,“黑名单”一样,点击一下会扩展开,再点击一下又会收缩回去。

    ExpandableListView是一个垂直滚动显示两级列表项的视图,与ListView不同的是,它可以有两层:每一层都能够被独立的展开并显示其子项。这些子项来自于与该视图关联的ExpandableListAdapter。
    每一个可以扩展的列表项的旁边都有一个指示符(箭头)用来说明该列表项目前的状态(这些状态一般是已经扩展开的列表项,还没有扩展开的列表项,子列表项和最后一个子列表项)。

    • 可以使用方法:setChildIndicator(Drawable),setGroupIndicator(Drawable)(或者相应的XML文件的属性) 去设置这些指示符的样式。当然也可以使用默认的指示符。
    • 和android.R.layout.simple_expandable_list_item_1,android.R.layout.simple_expandable_list_item_2和ListView一样,ExpandableListView也是一个需要Adapter作为桥梁来取得数据的控件。一般适用于ExpandableListView的Adapter都要继承BaseExpandableListAdapter这个类,并且必须重载getGroupView和getChildView这两个最为重要的方法。
    1. BaseExpandableListAdapter的主要重载方法如下:
    • public abstract ObjectgetChild (int groupPosition, int childPosition)
      取得与指定分组、指定子项目关联的数据.
      参数
      groupPosition 包含子视图的分组的位置.
      childPosition 指定的分组中的子视图的位置.
      返回
      与子视图关联的数据.
    • public abstract long getChildId (int groupPosition, intchildPosition)
      取得给定分组中给定子视图的ID. 该组ID必须在组中是唯一的.必须不同于其他所有ID(分组及子项目的ID).
      参数
      groupPosition 包含子视图的分组的位置.
      childPosition 要取得ID的指定的分组中的子视图的位置.
      返回
      与子视图关联的ID.
    • public abstract View getChildView (int groupPosition, intchildPosition, boolean isLastChild, View convertView, ViewGroup parent)
      取得显示给定分组给定子位置的数据用的视图.
      参数
      groupPosition 包含要取得子视图的分组位置.
      childPosition 分组中子视图(要返回的视图)的位置.
      isLastChild 该视图是否为组中的最后一个视图.
      convertView 如果可能,重用旧的视图对象.使用前你应该保证视图对象为非空,并且是否是合适的类型.如果该对象不能转换为可以正确显示数据的视图,该方法就创建新视图.不保证使用先前由 getChildView(int, int,boolean, View, ViewGroup)创建的视图.
      parent 该视图最终从属的父视图.
      返回
      指定位置相应的子视图.
    • public abstract int getChildrenCount (int groupPosition)
      取得指定分组的子元素数.
      参数
      groupPosition 要取得子元素个数的分组位置.
      返回
      指定分组的子元素个数.
    • public abstract long getCombinedChildId (long groupId, long childId)
      取得一览中可以唯一识别子条目的 ID(包括分组ID和子条目ID).可扩展列表要求每个条目 (分组条目和子条目)具有一个可以唯一识别列表中子条目和分组条目的ID. 该方法根据给定子条目ID和分组条目ID返回唯一识别ID.另外,如果 hasStableIds() 为真,该函数返回的ID必须是固定不变的.
      参数
      groupId 包含子条目ID的分组条目ID.
      childId 子条目的ID.
      返回
      可以在所有分组条目和子条目中唯一识别该子条目的ID(可能是固定不变的).
    • public abstract long getCombinedGroupId (long groupId)
      取得一览中可以唯一识别子条目的 ID(包括分组ID和子条目ID).可扩展列表要求每个条目 (分组条目和子条目)具有一个可以唯一识别列表中子条目和分组条目的ID. 该方法根据给定子条目ID和分组条目ID返回唯一识别ID.另外,如果 hasStableIds() 为真,该函数返回的ID必须是固定不变的.
      参数
      groupId 分组条目ID.
      返回
      可以在所有分组条目和子条目中唯一识别该分组条目的ID(可能是固定不变的).
    • public abstract Object getGroup (int groupPosition)
      取得与给定分组关联的数据.
      参数
      groupPosition 分组的位置.
      返回
      指定分组的数据.
      public abstract int getGroupCount ()
      取得分组数.
      返回
      分组数.
    • public abstract long getGroupId (int groupPosition)
      取得指定分组的ID.该组ID必须在组中是唯一的.必须不同于其他所有ID(分组及子项目的ID).
      参数
      groupPosition 要取得ID的分组位置.
      返回
      与分组关联的ID.
    • public abstract View getGroupView (int groupPosition, booleanisExpanded, View convertView, ViewGroup parent)
      取得用于显示给定分组的视图. 这个方法仅返回分组的视图对象, 要想获取子元素的视图对象,就需要调用 getChildView(int, int, boolean, View, ViewGroup).
      参数
      groupPosition 决定返回哪个视图的组位置 .
      isExpanded 该组是展开状态还是收起状态 .
      convertView 如果可能,重用旧的视图对象.使用前你应该保证视图对象为非空,并且是否是合适的类型.如果该对象不能转换为可以正确显示数据的视图,该方法就创建新视图.不保证使用先前由 getGroupView(int, boolean,View, ViewGroup)创建的视图.
      parent 该视图最终从属的父视图.
      返回
      指定位置相应的组视图.
    • public abstract boolean hasStableIds ()
      是否指定分组视图及其子视图的ID对应的后台数据改变也会保持该ID.
      返回
      是否相同的ID总是指向同一个对象.
    • public abstract boolean isChildSelectable (int groupPosition, intchildPosition)
      指定位置的子视图是否可选择.
      参数
      groupPosition 包含要取得子视图的分组位置.
      childPosition 分组中子视图的位置.
      返回
      是否子视图可选择.
    1. 优化扩展

    这样就完成了一个最简单的ExpandableListView的控件。
    在实际开发过程中,常常有不同的需求,比如每一个child需要不同的控件,每一个group或者child需要有图标,图标显示需要不一样,需要设置背景等各种各样能够让我们的程序变得美观的需求。那么下面就逐 一讨论一下ExpandableListView如何实现这些需求。

    • 为ExpandableListView设置背景,并且默认展开第n组,n从0开始计数,则只需要添加如下代码:
    	1. myExpandableListView.setBackgroundResource(R.drawable.background);
    	2. myExpandableListView.expandGroup(0);
    

    复制代码
    则效果如下:

    • 改变每个组前面的图标,并且图标样式随着合拢和展开不同,则只需要在res/drawable目录下定义文件:
      Indicator.xml
    	 <selector xmlns:android="http://schemas.android.com/apk/res/android">  
    	     <item android:state_expanded="true" android:drawable="@drawable/right" />  
    	     <item android:drawable="@drawable/down"></item>  
    	 </selector>	 
    

    复制代码

    • 在JAVA文件中添加:
     myExpandableListView.setGroupIndicator(this.getResources().getDrawable(R.drawable.indicator));
    

    复制代码
    效果如下:

    对于其他的属性设置,可以参考以下属性说明:

    • android:childDivider
      来分离子列表项的图片或者是颜色。注:图片不会完全显示,分离子列表项的是一条直线
    • android:childIndicator
      在子列表项旁边显示的指示符。注:可以是一个图片
    • android:childIndicatorLeft
      子列表项指示符的左边约束位置。注:即从左端0位置开始计数,比如,假设指示符是一个图标,给定这个属性值为3dip,则表示从左端起3dip开始显示此图标。
    • android:childIndicatorRight
      子列表项指示符的右边约束位置。注:表示右端到什么位置结束
    • android:groupIndicator
      在组列表项旁边显示的指示符。注:可以是一个图片。
    • android:indicatorLeft
      组列表项指示器的左边约束位置。注:表示左端从什么位置开始。
    • android:indicatorRight
      组列表项指示器的右边约束位置。注:表示右端到什么位置结束。
    1. 以疯狂android为例的基本用法介绍ExpandableListView其中几个重要的方法
    • getGroupCount()
                返回包含的组列表项的数量。
    @Override
            public int getGroupCount()
            {
                return armTypes.length;
            }
    
    • getGroup(int groupPosition)
      返回组列表的数据
    @Override
            public Object getGroup(int groupPosition)
            {
                return armTypes[groupPosition];
            }
    
    • getGroupId(int groupPosition)

    放回组列表组件的id

    @Override
            public long getGroupId(int groupPosition)
            {
                return groupPosition;
            }
    
    • getGroupView()

    该方法将返回的View对象将作为组列表项

    public View getGroupView(int groupPosition, boolean isExpanded,View convertView, ViewGroup parent)
            {
                LinearLayout ll = new LinearLayout(MainActivity.this);
                ll.setOrientation(0);
                ImageView logo = new ImageView(MainActivity.this);
                logo.setImageResource(logos[groupPosition]);
                ll.addView(logo);
                TextView textView = getTextView();
                textView.setText(getGroup(groupPosition).toString());
                ll.addView(textView);
                return ll;
            }
    
    • getChildCount()

    该方法返回特定组所包含的子列表项的数量

    @Override
            public int getChildrenCount(int groupPosition)
            {
                return arms[groupPosition].length;
            }
    
    • getChildView()

    该方法返回的View对象将作为特定组、特定位置的子列表项

    public View getChildView(int groupPosition, int childPosition,
                boolean isLastChild, View convertView, ViewGroup parent)
            {
                TextView textView = getTextView();
                textView.setText(getChild(groupPosition, childPosition)
                      .toString());
                return textView;
            }
    
    
    • getChildId()

    返回子列表组件的id

    public long getChildId(int groupPosition, int childPosition)
            {
                return childPosition;
            }
    
    • getChild(int groupPosition, int childPosition)

    返回子列表的数据

    public Object getChild(int groupPosition, int childPosition)
            {
                return arms[groupPosition][childPosition];
            }
            @Override
            public long getChildId(int groupPosition, int childPosition)
            {
                return childPosition;
            }
    
    • isChildSelectable()
      该方法返回true时,可以对子列表项设置监听

    • 监听函数
      1、listView.setOnChildClickListener()
      监听子列表项按下事件
      2、setOnGroupClickListener()
      监听组列表项按下事件

    疯狂android中代码文件

    package org.crazyit.ui;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.Gravity;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.AbsListView;
    import android.widget.BaseExpandableListAdapter;
    import android.widget.ExpandableListAdapter;
    import android.widget.ExpandableListView;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    public class MainActivity extends Activity
    {
      @Override
      public void onCreate(Bundle savedInstanceState)
      {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
    
          //创建一个BaseExpandableListAdapter对象
          ExpandableListAdapter adapter = new BaseExpandableListAdapter()
          {
            int[] logos = new int[]
            {
                R.drawable.p,
                R.drawable.z,
                R.drawable.t
            };
            private String[] armTypes = new String[]
                { "神族兵种", "虫族兵种", "人族兵种"};
            private String[][] arms = new String[][]
                {
                  { "狂战士", "龙骑士", "黑暗圣堂", "电兵" },
                  { "小狗", "刺蛇", "飞龙", "自爆飞机" },
                  { "机枪兵", "护士MM" , "幽灵" }
                };
    
    
            // 获取指定组位置、指定子列表项处的子列表项数据
            @Override
            public Object getChild(int groupPosition, int childPosition)
            {
                return arms[groupPosition][childPosition];
            }
            @Override
            public long getChildId(int groupPosition, int childPosition)
            {
                return childPosition;
            }
            @Override
            public int getChildrenCount(int groupPosition)
            {
                return arms[groupPosition].length;
            }
            private TextView getTextView()
            {
                AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
                      ViewGroup.LayoutParams.MATCH_PARENT, 64);
                TextView textView = new TextView(MainActivity.this);
                textView.setLayoutParams(lp);
                textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
                textView.setPadding(36, 0, 0, 0);
                textView.setTextSize(20);
                return textView;
            }
    
            // 该方法决定每个子选项的外观
            @Override
            public View getChildView(int groupPosition, int childPosition,
                boolean isLastChild, View convertView, ViewGroup parent)
            {
                TextView textView = getTextView();
                textView.setText(getChild(groupPosition, childPosition)
                      .toString());
                return textView;
            }
            // 获取指定组位置处的组数据
            @Override
            public Object getGroup(int groupPosition)
            {
                return armTypes[groupPosition];
            }
            @Override
            public int getGroupCount()
            {
                return armTypes.length;
            }
            @Override
            public long getGroupId(int groupPosition)
            {
                return groupPosition;
            }
            // 该方法决定每个组选项的外观
            @Override
            public View getGroupView(int groupPosition, boolean isExpanded,
                                View convertView, ViewGroup parent)
            {
                LinearLayout ll = new LinearLayout(MainActivity.this);
                ll.setOrientation(0);
                ImageView logo = new ImageView(MainActivity.this);
                logo.setImageResource(logos[groupPosition]);
                ll.addView(logo);
                TextView textView = getTextView();
                textView.setText(getGroup(groupPosition).toString());
                ll.addView(textView);
                return ll;
            }
            @Override
            public boolean isChildSelectable(int groupPosition,
                                      int childPosition)
            {
                return true;
            }
            @Override
            public boolean hasStableIds()
            {
                return true;
            }
          };
          ExpandableListView expandListView = (ExpandableListView) findViewById(R.id.list);
          expandListView.setAdapter(adapter);
      }
    }
    
    欢迎关注我的专属博客http://dyleaf.cn/
  • 相关阅读:
    hdu3336 Count the string 扩展KMP
    hdu3294 Girls' research manacher
    hdu3068 最长回文 manacher
    hdu2886 Lou 1 Zhuang 数学/快速幂
    hdu2841 Visible Trees 容斥原理
    hdu2819 Swap 二分图匹配
    RandomAccess接口的使用
    java集合框架
    java集合简介
    JDK,JRE,JVM的区别与联系
  • 原文地址:https://www.cnblogs.com/Dyleaf/p/7679839.html
Copyright © 2020-2023  润新知