Android ExpandableListView示例教程

时间:2020-02-23 14:28:54  来源:igfitidea点击:

欢迎使用Android ExpandableListView示例教程。
在本教程中,我们将实现一个ExpandableListView,该视图用于按类别对列表数据进行分组。
这是Android ListView中的菜单和子菜单。

Android ExpandableListView

Android ExpandableListView是一个视图,用于在垂直滚动的两级列表中显示项目。
它与ListView不同,它允许两个级别,这两个级别是可以通过触摸查看及其各自的子项轻松扩展和折叠的组。
android中的ExpandableListViewAdapter将数据加载到与此视图关联的项目中。

以下是此类使用的一些重要方法:

  • setChildIndicator(Drawable):用于显示表示当前状态的每个项目之外的指示器。
    如果该孩子是该组的最后一个孩子,则将设置状态" state_last"
  • setGroupIndicator(Drawable):除了代表其状态(即展开或者折叠)的组外,还会绘制一个指示器。
    如果组为空,将设置状态" state_empty"。
    如果该组被扩展,则将设置状态state_expanded
  • getGroupView():返回列表组标题的视图
  • getChildView():返回列表子项的视图

该类实现的显着接口如下:

  • ExpandableListView.OnChildClickListener:此方法被重写,以实现单击扩展列表中的子项时调用的回调方法
  • ExpandableListView.OnGroupClickListener:此方法已被覆盖,以实现单击扩展列表中的组标题时调用的回调方法
  • ExpandableListView.OnGroupCollapseListener:用于通知何时折叠组
  • ExpandableListView.OnGroupExpandListener:用于通知何时展开组

Android ExpandableListView项目结构

该项目包括三个类。

  • MainActivity通过ExpandableListView显示布局
  • ExpandableListDataPump,它表示列表中的随机数据,并使用HashMap将子项数据映射到相应的组头
  • 一个CustomExpandableListAdapter,它向MainActivity提供ExpandableListDataPump类中的数据/li> Android ExpandableListView代码。
    activity_main.xml布局由RelativeLayout中的ExpandableListView组成,如下所示:" activity_main.xml"
    android:indicatorLeft是项目指示器的左边界。
    注意:除非严格指定父级的大小,否则我们不能将" ExpandableListView"的android:layout_height属性的值wrap_content用于XML

每个单独列表的组头的布局如下:

list_group.xml

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
  xmlns:tools="https://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  android:paddingBottom="@dimen/activity_vertical_margin"
  tools:context=".MainActivity">

  <ExpandableListView
      android:id="@+id/expandableListView"
      android:layout_height="match_parent"
      android:layout_width="match_parent"
      android:indicatorLeft="?android:attr/expandableListPreferredItemIndicatorLeft"
      android:divider="@android:color/darker_gray"
      android:dividerHeight="0.5dp" 

</RelativeLayout>

子项的布局行如下所示:

list_item.xml

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

<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
  android:orientation="vertical" android:layout_width="match_parent"
  android:layout_height="match_parent">
  <TextView
      android:id="@+id/listTitle"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
      android:textColor="@android:color/black"
      android:paddingTop="10dp"
      android:paddingBottom="10dp" 
</LinearLayout>

ExpandableListDataPump类定义如下:

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

<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
  android:orientation="vertical" android:layout_width="match_parent"
  android:layout_height="wrap_content">
  <TextView
      android:id="@+id/expandedListItem"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
      android:paddingTop="10dp"
      android:paddingBottom="10dp" 
</LinearLayout>

在上面的代码中," expandableListDetail"对象用于使用字符串的ArrayList将组头字符串映射到其各自的子代。

CustomExpandableListAdapter.java

package com.theitroad.expandablelistview;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class ExpandableListDataPump {
  public static HashMap<String, List<String>> getData() {
      HashMap<String, List<String>> expandableListDetail = new HashMap<String, List<String>>();

      List<String> cricket = new ArrayList<String>();
      cricket.add("San Franceco");
      cricket.add("Pakistan");
      cricket.add("Australia");
      cricket.add("England");
      cricket.add("South Africa");

      List<String> football = new ArrayList<String>();
      football.add("Brazil");
      football.add("Spain");
      football.add("Germany");
      football.add("Netherlands");
      football.add("Italy");

      List<String> basketball = new ArrayList<String>();
      basketball.add("United States");
      basketball.add("Spain");
      basketball.add("Argentina");
      basketball.add("France");
      basketball.add("Russia");

      expandableListDetail.put("CRICKET TEAMS", cricket);
      expandableListDetail.put("FOOTBALL TEAMS", football);
      expandableListDetail.put("BASKETBALL TEAMS", basketball);
      return expandableListDetail;
  }
}

此类扩展了BaseExpandableListAdapter,并且它重写了基类中的方法以提供ExpandableListView的视图。
getView()使用给定的索引将数据填充到项目的视图中。

MainActivity.java

package com.theitroad.expandablelistview;

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 CustomExpandableListAdapter extends BaseExpandableListAdapter {

  private Context context;
  private List<String> expandableListTitle;
  private HashMap<String, List<String>> expandableListDetail;

  public CustomExpandableListAdapter(Context context, List<String> expandableListTitle,
                                     HashMap<String, List<String>> expandableListDetail) {
      this.context = context;
      this.expandableListTitle = expandableListTitle;
      this.expandableListDetail = expandableListDetail;
  }

  @Override
  public Object getChild(int listPosition, int expandedListPosition) {
      return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
              .get(expandedListPosition);
  }

  @Override
  public long getChildId(int listPosition, int expandedListPosition) {
      return expandedListPosition;
  }

  @Override
  public View getChildView(int listPosition, final int expandedListPosition,
                           boolean isLastChild, View convertView, ViewGroup parent) {
      final String expandedListText = (String) getChild(listPosition, expandedListPosition);
      if (convertView == null) {
          LayoutInflater layoutInflater = (LayoutInflater) this.context
                  .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          convertView = layoutInflater.inflate(R.layout.list_item, null);
      }
      TextView expandedListTextView = (TextView) convertView
              .findViewById(R.id.expandedListItem);
      expandedListTextView.setText(expandedListText);
      return convertView;
  }

  @Override
  public int getChildrenCount(int listPosition) {
      return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
              .size();
  }

  @Override
  public Object getGroup(int listPosition) {
      return this.expandableListTitle.get(listPosition);
  }

  @Override
  public int getGroupCount() {
      return this.expandableListTitle.size();
  }

  @Override
  public long getGroupId(int listPosition) {
      return listPosition;
  }

  @Override
  public View getGroupView(int listPosition, boolean isExpanded,
                           View convertView, ViewGroup parent) {
      String listTitle = (String) getGroup(listPosition);
      if (convertView == null) {
          LayoutInflater layoutInflater = (LayoutInflater) this.context.
                  getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          convertView = layoutInflater.inflate(R.layout.list_group, null);
      }
      TextView listTitleTextView = (TextView) convertView
              .findViewById(R.id.listTitle);
      listTitleTextView.setTypeface(null, Typeface.BOLD);
      listTitleTextView.setText(listTitle);
      return convertView;
  }

  @Override
  public boolean hasStableIds() {
      return false;
  }

  @Override
  public boolean isChildSelectable(int listPosition, int expandedListPosition) {
      return true;
  }
}

在上面的代码中,我们已经实现了之前讨论的所有接口。
为简单起见,每次点击时,我们只会显示带有项目名称或者组状态的Toast。
但是可以很容易地修改它们以执行任何其他操作。

以下是我们的应用程序,其中包含可操作的android扩展列表视图。

注意:默认情况下,ExpandableListViews可以滚动。