Bienvenue dans le didacticiel sur l’exemple de l’ExpandableListView Android. Dans ce didacticiel, nous implémenterons une ExpandableListView qui est utilisée pour regrouper les données de la liste par catégories. C’est un peu comme un menu et des sous-menus dans une Android ListView.
Android ExpandableListView
Android ExpandableListView est une vue qui montre des éléments dans une liste à deux niveaux qui défilent verticalement. Elle diffère d’une ListView en permettant deux niveaux, qui sont les groupes qui peuvent être facilement développés et réduits au toucher pour voir et leurs éléments enfants respectifs. ExpandableListViewAdapter dans Android charge les données dans les éléments associés à cette vue. Voici quelques méthodes importantes utilisées par cette classe :
- setChildIndicator(Drawable) : Ceci est utilisé pour afficher un indicateur à côté de chaque élément représentant l’état actuel. Si l’enfant est le dernier enfant d’un groupe, l’état
state_last
sera défini - setGroupIndicator(Drawable) : Un indicateur est dessiné à côté du groupe représentant son état, c’est-à-dire étendu ou réduit. Si le groupe est vide, l’état
state_empty
sera défini. Si le groupe est développé, l’étatstate_expanded
sera défini - getGroupView() : Il renvoie la vue pour l’en-tête du groupe de la liste
- getChildView() : Il renvoie la vue pour l’élément enfant de la liste
Les interfaces notables implémentées par cette classe sont les suivantes :
- ExpandableListView.OnChildClickListener : Ceci est remplacé pour implémenter la méthode de rappel qui est invoquée lorsqu’un enfant dans la liste étendue est cliqué
- ExpandableListView.OnGroupClickListener : Ceci est remplacé pour implémenter la méthode de rappel qui est invoquée lorsqu’un en-tête de groupe dans la liste étendue est cliqué
- ExpandableListView.OnGroupCollapseListener : Il est utilisé pour notifier lorsque un groupe est réduit
- ExpandableListView.OnGroupExpandListener : Il est utilisé pour notifier lorsque un groupe est étendu
Structure du projet Android ExpandableListView
Ce projet se compose de trois classes.
- A MainActivity that shows the layout with the ExpandableListView
- Un ExpandableListDataPump qui représente des données aléatoires dans une liste et mappe les données des éléments enfants aux en-têtes de groupe respectifs en utilisant un HashMap
- A CustomExpandableListAdapter which provides the MainActivity with the data from the ExpandableListDataPump class/li>
Code de ExpandableListView Android
La mise en page activity_main.xml se compose d’un ExpandableListView dans un RelativeLayout comme indiqué ci-dessous : 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>
Le android:indicatorLeft est la limite gauche pour un indicateur d’éléments. Remarque : Nous ne pouvons pas utiliser la valeur wrap_content pour l’attribut android:layout_height de ExpandableListView
en XML à moins que la taille du parent ne soit strictement spécifiée. La mise en page de l’en-tête de groupe de chaque liste individuelle est donnée ci-dessous : 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>
La ligne de mise en page des éléments enfants est donnée ci-dessous : 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>
La classe ExpandableListDataPump
est définie comme suit :
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;
}
}
Dans le code ci-dessus, l’objet expandableListDetail
est utilisé pour faire correspondre les chaînes d’en-tête de groupe à leurs enfants respectifs à l’aide d’une ArrayList de chaînes. 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;
}
}
Cette classe étend BaseExpandableListAdapter et remplace les méthodes de la classe de base pour fournir la vue de l’ExpandableListView. getView() remplit les données dans la vue de l’élément avec l’index donné. 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;
}
});
}
}
Dans le code ci-dessus, nous avons implémenté toutes les interfaces qui ont été discutées auparavant. Pour des raisons de simplicité, nous afficherons uniquement un Toast avec le nom de l’élément ou l’état du groupe à chaque clic. Mais ceux-ci peuvent être facilement modifiés pour effectuer d’autres opérations. Ci-dessous se trouve notre application avec la vue de liste extensible Android en action. Remarque: Les ExpandableListViews sont défilables par défaut. Cela marque la fin du tutoriel sur Android ExpandableListView. Vous pouvez télécharger le projet final Android ExpandableListView depuis le lien ci-dessous.
Source:
https://www.digitalocean.com/community/tutorials/android-expandablelistview-example-tutorial