Einführung in Android ExpandableListView
In diesem Tutorial wird erklärt, wie man eine ExpandableListView
in Android implementiert, um Listendaten nach Kategorien zu gruppieren. Dies ähnelt einem Menü und Untermenüs in einer ListView
.
Was ist eine ExpandableListView?
Eine ExpandableListView
zeigt Elemente in einer vertikal scrollenden Liste auf zwei Ebenen an. Im Gegensatz zu einer ListView
ermöglicht sie das einfache Ein- und Ausklappen von Gruppen durch Berühren. Der ExpandableListViewAdapter
lädt die Daten in die zugehörigen Elemente. Wichtige Methoden dieser Klasse sind:
setChildIndicator(Drawable)
: Zeigt einen Indikator neben jedem Element an, das den aktuellen Zustand repräsentiert.setGroupIndicator(Drawable)
: Zeichnet einen Indikator neben der Gruppe, der deren Zustand (erweitert oder eingeklappt) darstellt.getGroupView()
: Gibt die Ansicht für den Listengruppenkopf zurück.getChildView()
: Gibt die Ansicht für das Listenkindelement zurück.
Wichtige Schnittstellen
Die bemerkenswerten Schnittstellen dieser Klasse umfassen:
ExpandableListView.OnChildClickListener
: Wird überschrieben, um die Rückrufmethode zu implementieren, die aufgerufen wird, wenn ein Kind in der erweiterten Liste angeklickt wird.ExpandableListView.OnGroupClickListener
: Wird überschrieben, um die Rückrufmethode zu implementieren, die aufgerufen wird, wenn ein Gruppenkopf in der erweiterten Liste angeklickt wird.ExpandableListView.OnGroupCollapseListener
: Wird verwendet, um zu benachrichtigen, wenn eine Gruppe eingeklappt wird.ExpandableListView.OnGroupExpandListener
: Wird verwendet, um zu benachrichtigen, wenn eine Gruppe erweitert wird.
Projektstruktur
Dieses Projekt besteht aus drei Klassen:
MainActivity
: Zeigt das Layout mit derExpandableListView
.ExpandableListDataPump
: Repräsentiert zufällige Daten in einer Liste und ordnet die Kinddatenelemente den jeweiligen Gruppenköpfen zu.CustomExpandableListAdapter
: Stellt derMainActivity
die Daten aus derExpandableListDataPump
-Klasse zur Verfügung.
Beispielcode
Die Layout-Datei activity_main.xml
enthält eine ExpandableListView
in einem RelativeLayout
.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://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>
Implementierung der Adapterklasse
Die CustomExpandableListAdapter
-Klasse erweitert BaseExpandableListAdapter
und überschreibt dessen Methoden, um die Ansicht für die ExpandableListView
bereitzustellen.
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;
}
}
Hauptaktivität
Die MainActivity
implementiert die wichtigsten Schnittstellen und zeigt bei jedem Klick Toast-Nachrichten mit dem Namen des Elements oder dem Zustand der Gruppe an.
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;
}
});
}
}
Fazit
Dieses Tutorial zeigt, wie eine ExpandableListView
in Android implementiert wird. Diese flexible Komponente ermöglicht eine klare und organisierte Darstellung von Listen mit mehreren Ebenen und bietet eine einfache Möglichkeit zur Verwaltung und Anzeige von gruppierten Daten.
Beispielprojekt
Das komplette Android ExpandableListView
Projekt kann über den folgenden Link heruntergeladen werden.