zoukankan      html  css  js  c++  java
  • 多级列表——ExpandableListView

    ExpandableListView控件提供的是一个多级列表(一般是两级),我们先来看一下效果图,如图4.18所示为头部列表,单击其中的每一项下面会显示第二级列表,如图4.19所示。


     

    从图4.18和图4.19中可以看出,ExpandableListView为我们提供了一个极好的两级列表的展示控件。

    但是如何实现这个两级列表呢?既然ExpandableListView采用列表的形式,它也应该有一个适配器,但是它的适配器不是继承 BaseAdapter,而是要继承它独有的适配器BaseExpandableListAdapter,同时也需要实现其中的几个方法,如表4.3所 示。

    表4.3  BaseExpandableListAdapter中的方法


    方法名称 参数 说明
    getGroupId int groupPosition 获取组在给定的位置编号
    getChildId int groupPosition, int childPosition 获取给定组的孩子的ID
    getGroupCount   获取第一级列表的列数
    getChildrenCount int groupPosition 获取指定组中孩子的数量
    getGroup int groupPosition 获取给定组相关的数据
    getGroupView int groupPosition, boolean isExpanded, View convertView, ViewGroup parent 获取一个显示的视图给定组
    getChild int groupPosition, int childPosition 获取与孩子在给定的组相关的数据
    getChildView int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent 获取一个视图显示在给定的组的孩子的数据

    表4.3简单地介绍了BaseExpandableListAdapter中的方法,下面来实现图4.18和图4.19中的效果。

    (1)布局文件。从图中可以看出我们需要用到3个布局文件:一个是声明ExpandableListView,一个声明第一级菜单,一个是第二级菜单的布局文件。
    声明ExpandableListView的布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical" android:layout_width="fill_parent"
     android:layout_height="fill_parent" android:background="@drawable/default_bg">

     <ExpandableListView android:id="@+id/list"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
            android:layout_alignParentLeft="true"/>

    </RelativeLayout>

    第一级菜单布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="40dip"
        android:layout_gravity="center_horizontal" >
        <LinearLayout
            android:id="@+id/layout_013"
            android:layout_width="fill_parent"
            android:layout_height="40dip"
            android:orientation="horizontal" >

            <ImageView
                android:id="@+id/ImageView01"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:paddingTop="10dip"
                android:src="@drawable/user_group" >
            </ImageView>
            <RelativeLayout
                android:id="@+id/layout_013"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" >
                <TextView
                    android:id="@+id/content_001"
                    android:layout_width="wrap_content"
                    android:layout_height="fill_parent"
                    android:layout_gravity="center_vertical"
                    android:gravity="center_vertical"
                    android:paddingLeft="10px"
                    android:textColor="#FFFFFF"
                    android:textSize="26px" >
                </TextView>
                <ImageView
                    android:id="@+id/tubiao"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true" >
                </ImageView>
            </RelativeLayout>
        </LinearLayout>
    </LinearLayout>

    第二级菜单布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/childlayout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal" >
        <ImageView
            android:id="@+id/child_image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="40dip"
            android:background="@drawable/child_image"
            android:paddingTop="10dip" >
        </ImageView>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
            <TextView
                android:id="@+id/child_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:gravity="center_vertical"
                android:text=""
                android:textSize="16dip" >
            </TextView>
            <TextView
                android:id="@+id/child_text2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:gravity="center_vertical"
                android:text=""
                android:textSize="12dip" >
            </TextView>
        </LinearLayout>
    </LinearLayout>

    (2)写一个类ExAdapter继承BaseExpandableListAdapter,并且实现它的方法。获取给定组的一个显示的视图:

     //获取一个显示的视图给定组
         public View getGroupView(int groupPosition, boolean isExpanded,
           View convertView, ViewGroup parent) {
       View view = convertView;
       if (view == null) {
       // 通过getSystemService方法实例化一个视图的填充器
        LayoutInflater inflater = (LayoutInflater) getSystemService
    (Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.member_listview, null);
       }
        TextView title = (TextView) view.findViewById
    (R.id.content_001);
        title.setText(getGroup(groupPosition).toString());

        ImageView image=(ImageView) view.findViewById(R.id.tubiao);
        //判断实例可以展开,如果可以则改变右侧的图标
        if(isExpanded)
         image.setBackgroundResource(R.drawable.btn_browser2);
        else image.setBackgroundResource(R.drawable.btn_browser);
        
          return view;
         }

    获取给定组的相关数据及显示的列数:

     //获取给定组相关的数据
         public Object getGroup(int groupPosition) {
          return groupData.get(groupPosition).get(G_TEXT).toString();
         }
         //获取第一级列表的列数
         public int getGroupCount() {
       return groupData.size();
         }

    获取一个视图显示在给定的组的孩子的数据:
     public View getChildView(int groupPosition, int childPosition,
           boolean isLastChild, View convertView, ViewGroup parent) {
          View view = convertView;
       if (view == null) {
        //填充视图
        LayoutInflater inflater = (LayoutInflater) getSystemService
    (Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.member_childitem, null); 
       }
           final TextView title = (TextView) view.findViewById
    (R.id.child_text);
         title.setText(childData.get(groupPosition).
    get(childPosition).get(C_TEXT1).toString());   
        final TextView title2 = (TextView) view.findViewById
    (R.id.child_text2);
         title2.setText(childData.get(groupPosition).
    get(childPosition).get(C_TEXT2).toString());
       
       return view;
         }

    获取与孩子在给定的组相关的数据,以及孩子组显示的列数:

         //获取与孩子在给定的组相关的数据
         public Object getChild(int groupPosition, int childPosition) {
          return childData.get(groupPosition).get(childPosition).get(C_TEXT1).toString();
         }
         //获取指定组中孩子的数量
         public int getChildrenCount(int groupPosition) {
          return childData.get(groupPosition).size();
         }

    (3)通过方法findViewById获取ExpandableListView的实例,为其设置数据显示的适配器。

    for (int i = 0; i < 5; i++) {
                Map<String, String> curGroupMap = new HashMap<String, String>();
                groupData.add(curGroupMap);
                curGroupMap.put(G_TEXT, "Group " + i);
                 
                List<Map<String, String>> children = new ArrayList<Map<String, String>>();
                for (int j = 0; j < 5; j++) {
                    Map<String, String> curChildMap = new HashMap<String, String>();
                    children.add(curChildMap);
                    curChildMap.put(C_TEXT1, "Child " + j);
                    curChildMap.put(C_TEXT2, "Child " + j);
                }
                childData.add(children);
            }
           
            adapter=new ExAdapter(ExpanListViewDemoActivity.this);
            exList = (ExpandableListView) findViewById(R.id.list);
        exList.setAdapter(adapter);
        exList.setGroupIndicator(null);
        exList.setDivider(null);

    从这个实例中可以看到,ExpandableListView的功能主要在于它的适配器,只要写好了适配器,列表就会显示出来。上面的例子中,我们 没有添加,单击第二级列表不会有任何反应,如果要有点击的效果,需要为ExpandableListView设置一个事 件:setOnChildClickListener,实例化OnChildClickListener类,实现其中的public boolean onChildClick(ExpandableListView parent, View v,int groupPosition, int childPosition, long id)方法,这个事件就留给读者去实现。

  • 相关阅读:
    【大厂面试】字节跳动、京东等大厂面试题分享,已拿字节offer~
    听说这十道面试题,把百分之八十的程序员都淘汰了?不是吧,阿sir
    阿里大神的刷题笔记.pdf
    在家学了6个月,拿到阿里offer!
    【面试题】2020年底总结200道带答案的常见Java面试题!
    面试一家小公司,被问了 1 个小时并发编程。。全程已记录!
    分享一份技术书籍《Java 8 》PDF版,可自行下载
    Delphi的TDataSetProvider、TDataSet、TAdoQuery、TDataSource、TDataModule控件的组合使用
    初学Delphi与sql server的存储过程
    delphi简单的分页实现(高手可以不看)
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/4724102.html
Copyright © 2011-2022 走看看