Welcome to Android ExpandableListView Example Tutorial. In this tutorial we’ll implement an ExpandableListView which is used to group list data by categories. It’s sort of menu and submenus in a Android ListView.
欢迎使用Android ExpandableListView示例教程。 在本教程中,我们将实现一个ExpandableListView ,它用于按类别对列表数据进行分组。 这是Android ListView中的菜单和子菜单。
Android ExpandableListView (Android ExpandableListView)
Android ExpandableListView is a view that shows items in a vertically scrolling two-level list. It differs from a ListView by allowing two levels which are groups that can be easily expanded and collapsed by touching to view and their respective children items.
ExpandableListViewAdapter in android loads the data into the items associated with this view.
Android ExpandableListView是一个视图,用于在垂直滚动的两级列表中显示项目。 它与ListView的不同之处在于,它允许两个级别,这两个级别是可以通过触摸查看及其相应子项轻松扩展和折叠的组 。
android中的ExpandableListViewAdapter将数据加载到与此视图关联的项目中。
Following are some important methods that are used by this class :
以下是此类使用的一些重要方法:
- setChildIndicator(Drawable) : This is used to show an indicator besides each item representing the current state. If the child is the last child for a group, the state
state_last
will be set setChildIndicator(Drawable) :用于显示表示当前状态的每个项目之外的指示器。 如果该子项是组的最后一个子项,则将设置状态state_last
- setGroupIndicator(Drawable) : An indicator is drawn besides the group representing its state i.e. expanded or collapsed. If the group is empty, the state
state_empty
will be set. If the group is expanded, the statestate_expanded
will be set setGroupIndicator(Drawable) :除了代表其状态(即展开或折叠)的组之外,还绘制了一个指示器。 如果组为空,将设置状态state_empty
。 如果组被扩展,则将设置状态state_expanded
- getGroupView() : It returns view for the list group header getGroupView() :返回列表组标题的视图
- getChildView() : It returns view for list child item getChildView() :返回列表子项的视图
The notable interfaces that are implemented by this class are given below :
该类实现的显着接口如下:
- ExpandableListView.OnChildClickListener : This is overridden to implement the callback method that’s invoked when a child in the expanded list is clicked ExpandableListView.OnChildClickListener :重写此方法,以实现单击扩展列表中的子项时调用的回调方法。
- ExpandableListView.OnGroupClickListener : This is overridden to implement the callback method that’s invoked when a group header in the expanded list is clicked ExpandableListView.OnGroupClickListener :重写此方法以实现单击扩展列表中的组标题时调用的回调方法。
- ExpandableListView.OnGroupCollapseListener : It is used for notifying when a group is collapsed ExpandableListView.OnGroupCollapseListener :用于通知何时折叠组
- ExpandableListView.OnGroupExpandListener : It is used to notify when a group is expanded ExpandableListView.OnGroupExpandListener :用于通知何时展开组
Android ExpandableListView项目结构 (Android ExpandableListView Project Structure)
This project consists of three classes.
该项目包括三个班级。
- A MainActivity that shows the layout with the ExpandableListView MainActivity通过ExpandableListView显示布局
- An ExpandableListDataPump which represents a random data in a List and maps the child item data to the respective group headers using a HashMap ExpandableListDataPump ,它表示列表中的随机数据,并使用HashMap将子项数据映射到相应的组头
- A CustomExpandableListAdapter which provides the MainActivity with the data from the ExpandableListDataPump class/li> 一个CustomExpandableListAdapter ,它为MainActivity提供ExpandableListDataPump类中的数据/ li>
Android ExpandableListView代码 (Android ExpandableListView Code)
The activity_main.xml layout consists of an ExpandableListView in a RelativeLayout as shown below :
activity_main.xml布局由RelativeLayout中的ExpandableListView组成,如下所示:
activity_main.xml
activity_main.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>
The android:indicatorLeft is the left bound for an items indicator.
android:indicatorLeft是商品指标的左边界。
Note : We cannot use the value wrap_content for the android:layout_height attribute of the ExpandableListView
in XML unless the parent’s size is strictly specified
注意 :除非严格指定父级的大小,否则我们不能在XML中的ExpandableListView
的android:layout_height属性中使用值wrap_content
The layout of the group header of each individual list is given below :
每个单独列表的组标题的布局如下:
list_group.xml
list_group.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>
The layout row of the child items is given below :
子项的布局行如下所示:
list_item.xml
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="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>
The ExpandableListDataPump
class is defined as below:
ExpandableListDataPump
类的定义如下:
package com.journaldev.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("India");
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;
}
}
In the above code the expandableListDetail
object is used to map the group header strings to their respective children using an ArrayList of Strings.
在上面的代码中, expandableListDetail
对象用于使用字符串的ArrayList将组头字符串映射到它们各自的子代。
CustomExpandableListAdapter.java
CustomExpandableListAdapter.java
package com.journaldev.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;
}
}
This class extends BaseExpandableListAdapter and it overrides the methods in the base class to provide the view for the ExpandableListView. getView() fills in the data into the item’s view with the given index.
此类扩展了BaseExpandableListAdapter,并且它重写了基类中的方法以提供ExpandableListView的视图。 getView()使用给定的索引将数据填充到项目的视图中。
MainActivity.java
MainActivity.java
package com.journaldev.expandablelistview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MainActivity extends AppCompatActivity {
ExpandableListView expandableListView;
ExpandableListAdapter expandableListAdapter;
List<String> expandableListTitle;
HashMap<String, List<String>> expandableListDetail;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
expandableListView = (ExpandableListView) findViewById(R.id.expandableListView);
expandableListDetail = ExpandableListDataPump.getData();
expandableListTitle = new ArrayList<String>(expandableListDetail.keySet());
expandableListAdapter = new CustomExpandableListAdapter(this, expandableListTitle, expandableListDetail);
expandableListView.setAdapter(expandableListAdapter);
expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
@Override
public void onGroupExpand(int groupPosition) {
Toast.makeText(getApplicationContext(),
expandableListTitle.get(groupPosition) + " List Expanded.",
Toast.LENGTH_SHORT).show();
}
});
expandableListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
@Override
public void onGroupCollapse(int groupPosition) {
Toast.makeText(getApplicationContext(),
expandableListTitle.get(groupPosition) + " List Collapsed.",
Toast.LENGTH_SHORT).show();
}
});
expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
Toast.makeText(
getApplicationContext(),
expandableListTitle.get(groupPosition)
+ " -> "
+ expandableListDetail.get(
expandableListTitle.get(groupPosition)).get(
childPosition), Toast.LENGTH_SHORT
).show();
return false;
}
});
}
}
In the above code we’ve implemented all the interfaces that were discussed before. For the sake of simplicity, we’ll only display a Toast with the name of the item or the state of the group for every click. But these can be easily modified to perform any other operations.
在上面的代码中,我们已经实现了之前讨论的所有接口。 为简单起见,每次单击时,我们仅显示带有项目名称或组状态的Toast。 但是可以很容易地修改它们以执行任何其他操作。
Below is our app with android expandable list view in action.
以下是我们的应用程序,其中包含可操作的android扩展列表视图。
Note: ExpandableListViews are scrollable by default.
注意 :ExpandableListViews默认是可滚动的。
This brings an end to Android ExpandableListView tutorial. You can download the final Android ExpandableListView Project from the below link.
这样就结束了Android ExpandableListView教程。 您可以从下面的链接下载最终的Android ExpandableListView项目 。
翻译自: https://www.journaldev.com/9942/android-expandablelistview-example-tutorial