ברוך הבא לשורה הנפתחת של דוגמה של Android ExpandableListView. במהלך הדרך נממש ExpandableListView המשמשת לקבץ נתוני רשימה לפי קטגוריות. זו סוג של תפריט עם תתי תפריטים בתוך Android ListView.
Android ExpandableListView
Android ExpandableListView היא תצוגה המציגה פריטים ברשימה גלילה אנכית בשתי רמות. היא שונה מ-ListView באפשרות להציג שתי רמות – קבוצות שניתן לפתוח ולסגור בקלות על ידי לחיצה לצפות ואת פריטי הילד המתאימים להם. ExpandableListViewAdapter ב-Android טוען את הנתונים לפריטים הקשורים לתצוגה זו. הנה כמה מתוך השיטות החשובות שמשתמשות במחלקה זו:
- setChildIndicator(Drawable) : משמשת להצגת אינדיקטור לצד כל פריט, המייצג את המצב הנוכחי. אם הילד הוא הילד האחרון של קבוצה, יוגדר המצב
state_last
- setGroupIndicator(Drawable) : נצבע אינדיקטור לצד הקבוצה, המייצג את המצב שלה – האם היא נפתחה או נסגרה. אם הקבוצה ריקה, יוגדר המצב
state_empty
. אם הקבוצה נפתחת, יוגדר המצבstate_expanded
- getGroupView() : מחזירה תצוגה עבור כותרת קבוצת הרשימה
- getChildView() : הוא מחזיר תצוגה עבור פריט ילד ברשימה
ממשקי הבולטים שמיושמים על ידי מחלקה זו מופיעים להלן:
- ExpandableListView.OnChildClickListener : זה נדרש להתעלם וליישם את שיטת הקריאה המחזירה שנקראת כאשר נלחץ פריט ילד ברשימה המורחבת
- ExpandableListView.OnGroupClickListener : זה נדרש להתעלם וליישם את שיטת הקריאה המחזירה שנקראת כאשר נלחץ כותרת קבוצה ברשימה המורחבת
- ExpandableListView.OnGroupCollapseListener : נמשך להתקיים כאשר קבוצה מתמטת
- ExpandableListView.OnGroupExpandListener : זה משמש להודיע כאשר קבוצה מתרחבת
מבנה הפרויקט של Android ExpandableListView
- A MainActivity that shows the layout with the ExpandableListView
- ExpandableListDataPump אשר מייצג נתוני רשימה אקראיים וממפה את נתוני פריטי הילד לכותרות הקבוצה המתאימות באמצעות HashMap
- A CustomExpandableListAdapter which provides the MainActivity with the data from the ExpandableListDataPump class/li>
קוד ExpandableListView של אנדרואיד
תצוגת activity_main.xml מכילה ExpandableListView בתוך RelativeLayout כפי שמוצג למטה: 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>
ה-attribue android:indicatorLeft הוא הגבול השמאלי של מחוון פריטים. הערה: אנו לא יכולים להשתמש בערך wrap_content עבור ה-attribute android:layout_height של ExpandableListView
ב-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>
השורה התצוגה של פריטי הילד ניתנת למטה: 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>
המחלקה 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;
}
}
בקוד למעלה, האובייקט expandableListDetail
משמש למפה את מחרוזות כותרת הקבוצה לילדיהן התואמים באמצעות ArrayList של Strings. 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;
}
}
מחלקה זו מרחיבה את BaseExpandableListAdapter ומחליפה את השיטות במחלקת הבסיס כדי לספק את התצוגה עבור ExpandableListView. getView() ממלא את הנתונים בתצוגת הפריט עם האינדקס הנתון. 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;
}
});
}
}
בקוד למעלה הטמנו את כל הממשקים שנדונו קודם לכן. לצורך הפשטות, נציג רק Toast שמציג את שם הפריט או מצב הקבוצה בכל לחיצה. אך ניתן לשנות את זה בקלות כדי לבצע פעולות נוספות. למטה יש את האפליקציה שלנו עם Android ExpandableListView בפעולה. הערה: ExpandableListViews יכולים להיגלול כברירת מחדל. זה מסיים את מדריך Android ExpandableListView. ניתן להוריד את הפרויקט הסופי של Android ExpandableListView מהקישור למטה. פרויקט Android ExpandableListView הורדה מהקישור למטה.
Source:
https://www.digitalocean.com/community/tutorials/android-expandablelistview-example-tutorial