ExpandableListView使用介绍

本文翻译自:http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/


Expandable list view 是通过分类列表来组织数据的一种ListView。 在用户点击分组时他可以自动折叠或展开分组,如果你之前不熟悉ListView请先点击下面链了解一下ListView的基本用法 Android ListView Tutorial。

下面我们开始学习ExpandableListView 如何使用。

1.创建一个新的工程,并且将main activity 命名为MainActivity.java

2.为了创建一个Expandable list view 视图,我们需要三个xml布局文件,第一个是main listview,第二个是ExpandableListView中的分类Iten使用的布局文件,第三个是展开后的列表的Item布局文件(ChildItem的布局文件)

activity_main.xml

<?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="fill_parent"

    android:orientation="vertical"

    android:background="#f4f4f4" >

 

            <ExpandableListView

                android:id="@+id/lvExp"

                android:layout_height="match_parent"

                android:layout_width="match_parent"/>   

</LinearLayout>

3.创建第二个布局文件,作为Group Header(分类的Item)。我创建了一个叫 list_group.xml 的布局文件,如下所示

list_group.xml

<?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="wrap_content"

    android:orientation="vertical"

    android:padding="8dp"

    android:background="#000000">

    <TextView

        android:id="@+id/lblListHeader"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"

        android:textSize="17dp"

        android:textColor="#f9f93d" />

</LinearLayout>

4.再创建一个布局文件,也就是展开列表时为其中的子Item提供布局的文件,我为他命名为 list_item.xml ,代码如下所示:

list_item.xml

<?xml version="1.0" encoding="utf-8"?>

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

    android:layout_width="match_parent"

    android:layout_height="55dip"

    android:orientation="vertical" >

 

    <TextView

        android:id="@+id/lblListItem"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:textSize="17dip"

        android:paddingTop="5dp"

        android:paddingBottom="5dp"

        android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft" />

</LinearLayout>

5.我使用一个自定义的Adapter类去创建列表视图。创建一个新的类命名为ExpandableListAdapter.java 并且继承自BaseExpandableListAdapter这个类为创建ListView提供了许多基础的方法,其中getGroupView() –返回分组的Header视图

getChildView() – 返回分组展开后的列表视图

下面是自定义Adapter的代码:

ExpandableListAdapter.java

import java.util.HashMap;

import java.util.List;

 

import android.content.Context;

import android.graphics.Typeface;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseExpandableListAdapter;

import android.widget.TextView;

 

public class ExpandableListAdapter extends BaseExpandableListAdapter {

 

    private Context _context;

    private List<String> _listDataHeader; // header titles

    // child data in format of header title, child title

    private HashMap<String, List<String>> _listDataChild;

 

    public ExpandableListAdapter(Context context, List<String> listDataHeader,

            HashMap<String, List<String>> listChildData) {

        this._context = context;

        this._listDataHeader = listDataHeader;

        this._listDataChild = listChildData;

    }

 

    @Override

    public Object getChild(int groupPosition, int childPosititon) {

        return this._listDataChild.get(this._listDataHeader.get(groupPosition))

                .get(childPosititon);

    }

 

    @Override

    public long getChildId(int groupPosition, int childPosition) {

        return childPosition;

    }

 

    @Override

    public View getChildView(int groupPosition, final int childPosition,

            boolean isLastChild, View convertView, ViewGroup parent) {

 

        final String childText = (String) getChild(groupPosition, childPosition);

 

        if (convertView == null) {

            LayoutInflater infalInflater = (LayoutInflater) this._context

                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            convertView = infalInflater.inflate(R.layout.list_item, null);

        }

 

        TextView txtListChild = (TextView) convertView

                .findViewById(R.id.lblListItem);

 

        txtListChild.setText(childText);

        return convertView;

    }

 

    @Override

    public int getChildrenCount(int groupPosition) {

        return this._listDataChild.get(this._listDataHeader.get(groupPosition))

                .size();

    }

 

    @Override

    public Object getGroup(int groupPosition) {

        return this._listDataHeader.get(groupPosition);

    }

 

    @Override

    public int getGroupCount() {

        return this._listDataHeader.size();

    }

 

    @Override

    public long getGroupId(int groupPosition) {

        return groupPosition;

    }

 

    @Override

    public View getGroupView(int groupPosition, boolean isExpanded,

            View convertView, ViewGroup parent) {

        String headerTitle = (String) getGroup(groupPosition);

        if (convertView == null) {

            LayoutInflater infalInflater = (LayoutInflater) this._context

                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            convertView = infalInflater.inflate(R.layout.list_group, null);

        }

        TextView lblListHeader = (TextView) convertView

                .findViewById(R.id.lblListHeader);

        lblListHeader.setTypeface(null, Typeface.BOLD);

        lblListHeader.setText(headerTitle);

 

        return convertView;

    }

 

    @Override

    public boolean hasStableIds() {

        return false;

    } 

    @Override

    public boolean isChildSelectable(int groupPosition, int childPosition) {

        return true;

    }

}


6.当你完成了自定义Adapter以后,打开你的 MainActivity.java做如下操作,创建List view所需要的数据,并且将他们传递到Adapter中,来构建ExpandableListView,代码如下:

package info.androidhive.expandablelistview;

 

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.widget.ExpandableListView;

import android.widget.ExpandableListView.OnChildClickListener;

import android.widget.ExpandableListView.OnGroupClickListener;

import android.widget.ExpandableListView.OnGroupCollapseListener;

import android.widget.ExpandableListView.OnGroupExpandListener;

import android.widget.Toast;

 

public class MainActivity extends Activity {

 

    ExpandableListAdapter listAdapter;

    ExpandableListView expListView;

    List<String> listDataHeader;

    HashMap<String, List<String>> listDataChild;

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

 

        // get the listview

        expListView = (ExpandableListView) findViewById(R.id.lvExp);

 

        // preparing list data

        prepareListData();

 

        listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);

 

        // setting list adapter

        expListView.setAdapter(listAdapter);

    }

 

    /*

     * Preparing the list data

     */

    private void prepareListData() {

        listDataHeader = new ArrayList<String>();

        listDataChild = new HashMap<String, List<String>>();

 

        // Adding child data

        listDataHeader.add("Top 250");

        listDataHeader.add("Now Showing");

        listDataHeader.add("Coming Soon..");

 

        // Adding child data

        List<String> top250 = new ArrayList<String>();

        top250.add("The Shawshank Redemption");

        top250.add("The Godfather");

        top250.add("The Godfather: Part II");

        top250.add("Pulp Fiction");

        top250.add("The Good, the Bad and the Ugly");

        top250.add("The Dark Knight");

        top250.add("12 Angry Men");

 

        List<String> nowShowing = new ArrayList<String>();

        nowShowing.add("The Conjuring");

        nowShowing.add("Despicable Me 2");

        nowShowing.add("Turbo");

        nowShowing.add("Grown Ups 2");

        nowShowing.add("Red 2");

        nowShowing.add("The Wolverine");

 

        List<String> comingSoon = new ArrayList<String>();

        comingSoon.add("2 Guns");

        comingSoon.add("The Smurfs 2");

        comingSoon.add("The Spectacular Now");

        comingSoon.add("The Canyons");

        comingSoon.add("Europa Report");

        listDataChild.put(listDataHeader.get(0), top250); // Header, Child data

        listDataChild.put(listDataHeader.get(1), nowShowing);

        listDataChild.put(listDataHeader.get(2), comingSoon);

    }

}

好了,以上工作都完成后,你就可以运行一下你的代码了。下来就会看到下面的样子:

ExpandableListView使用介绍

ListVeiw 子 Item 点击事件监听

为了监听ListView 子 Item的点击事件可以通过实现setOnChildClickListener这个接口来完成,代码如下:

expListView.setOnChildClickListener( new OnChildClickListener() {
 
             @Override
             public boolean onChildClick(ExpandableListView parent, View v,
                     int groupPosition, int childPosition, long id) {
                 Toast.makeText(
                         getApplicationContext(),
                         listDataHeader.get(groupPosition)
                                 + " : "
                                 + listDataChild.get(
                                         listDataHeader.get(groupPosition)).get(
                                         childPosition), Toast.LENGTH_SHORT)
                         .show();
                 return false ;
             }

        });


列表展开事件监听

实现setOnGroupExpandListener监听,在列表项展开时,它将被触发并执行。


总结:ExpandableListView和ListView的用法差不多,它就相当于一个ListView的集合,每一个Item展开后又是一个ListView。因此他需要一个main.xml在这个里面声明ExpandableListView控件,然后需要一个ListItem(group header)来代表每个group Item ,然后需要一个xml来对展开后的子ListView的Item进行布局。

你可能感兴趣的:(ExpandableListView使用介绍)