Android ExpandableListView Example.
Android Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.as400samplecode"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Application main Layout - activity_main.xml
<?xml version="1.0" encoding="UTF-8"?> <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"> <SearchView android:id="@+id/search" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:iconifiedByDefault="false" /> <ExpandableListView android:id="@+id/expandableList" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/search" /> </RelativeLayout>
ExpandableListView Child Row Layout - child_row.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"> <TextView android:id="@+id/code" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:paddingLeft="35sp" android:paddingRight="10dp" android:text="USA" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/code" android:text="United States Of America" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/population" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:paddingRight="5dp" android:text="200,000,000" android:textAppearance="?android:attr/textAppearanceMedium" /> </RelativeLayout>
ExpandableListView Header Row Layout - group_row.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="55dip" android:orientation="vertical"> <TextView android:id="@+id/heading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="35sp" android:textAppearance="?android:attr/textAppearanceLarge" android:textStyle="bold" /> </LinearLayout>
Child Row Country Object - Country.java
package com.as400samplecode;
public class Country {
private String code = "";
private String name = "";
private int population = 0;
public Country(String code, String name, int population) {
super();
this.code = code;
this.name = name;
this.population = population;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
}
Group Heading Continent Object - Continent.java
package com.as400samplecode;
import java.util.ArrayList;
public class Continent {
private String name;
private ArrayList<Country> countryList = new ArrayList<Country>();
public Continent(String name, ArrayList<Country> countryList) {
super();
this.name = name;
this.countryList = countryList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<Country> getCountryList() {
return countryList;
}
public void setCountryList(ArrayList<Country> countryList) {
this.countryList = countryList;
};
}
Custom BaseExpandableListAdapter with filter - MyListAdapter.java
package com.as400samplecode;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Locale;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
public class MyListAdapter extends BaseExpandableListAdapter {
private Context context;
private ArrayList<Continent> continentList;
private ArrayList<Continent> originalList;
public MyListAdapter(Context context, ArrayList<Continent> continentList) {
this.context = context;
this.continentList = new ArrayList<Continent>();
this.continentList.addAll(continentList);
this.originalList = new ArrayList<Continent>();
this.originalList.addAll(continentList);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
ArrayList<Country> countryList = continentList.get(groupPosition).getCountryList();
return countryList.get(childPosition);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View view, ViewGroup parent) {
Country country = (Country) getChild(groupPosition, childPosition);
if (view == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.child_row, null);
}
TextView code = (TextView) view.findViewById(R.id.code);
TextView name = (TextView) view.findViewById(R.id.name);
TextView population = (TextView) view.findViewById(R.id.population);
code.setText(country.getCode().trim());
name.setText(country.getName().trim());
population.setText(NumberFormat.getNumberInstance(Locale.US).format(country.getPopulation()));
return view;
}
@Override
public int getChildrenCount(int groupPosition) {
ArrayList<Country> countryList = continentList.get(groupPosition).getCountryList();
return countryList.size();
}
@Override
public Object getGroup(int groupPosition) {
return continentList.get(groupPosition);
}
@Override
public int getGroupCount() {
return continentList.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isLastChild, View view,
ViewGroup parent) {
Continent continent = (Continent) getGroup(groupPosition);
if (view == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.group_row, null);
}
TextView heading = (TextView) view.findViewById(R.id.heading);
heading.setText(continent.getName().trim());
return view;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
public void filterData(String query){
query = query.toLowerCase();
Log.v("MyListAdapter", String.valueOf(continentList.size()));
continentList.clear();
if(query.isEmpty()){
continentList.addAll(originalList);
}
else {
for(Continent continent: originalList){
ArrayList<Country> countryList = continent.getCountryList();
ArrayList<Country> newList = new ArrayList<Country>();
for(Country country: countryList){
if(country.getCode().toLowerCase().contains(query) ||
country.getName().toLowerCase().contains(query)){
newList.add(country);
}
}
if(newList.size() > 0){
Continent nContinent = new Continent(continent.getName(),newList);
continentList.add(nContinent);
}
}
}
Log.v("MyListAdapter", String.valueOf(continentList.size()));
notifyDataSetChanged();
}
}
Application Activity - MainActivity.java
package com.as400samplecode;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.view.Menu;
import android.widget.ExpandableListView;
import android.widget.SearchView;
public class MainActivity extends Activity implements
SearchView.OnQueryTextListener, SearchView.OnCloseListener{
private SearchView search;
private MyListAdapter listAdapter;
private ExpandableListView myList;
private ArrayList<Continent> continentList = new ArrayList<Continent>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
search = (SearchView) findViewById(R.id.search);
search.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
search.setIconifiedByDefault(false);
search.setOnQueryTextListener(this);
search.setOnCloseListener(this);
//display the list
displayList();
//expand all Groups
expandAll();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
//method to expand all groups
private void expandAll() {
int count = listAdapter.getGroupCount();
for (int i = 0; i < count; i++){
myList.expandGroup(i);
}
}
//method to expand all groups
private void displayList() {
//display the list
loadSomeData();
//get reference to the ExpandableListView
myList = (ExpandableListView) findViewById(R.id.expandableList);
//create the adapter by passing your ArrayList data
listAdapter = new MyListAdapter(MainActivity.this, continentList);
//attach the adapter to the list
myList.setAdapter(listAdapter);
}
private void loadSomeData() {
ArrayList<Country> countryList = new ArrayList<Country>();
Country country = new Country("BMU","Bermuda",10000000);
countryList.add(country);
country = new Country("CAN","Canada",20000000);
countryList.add(country);
country = new Country("USA","United States",50000000);
countryList.add(country);
Continent continent = new Continent("North America",countryList);
continentList.add(continent);
countryList = new ArrayList<Country>();
country = new Country("CHN","China",10000100);
countryList.add(country);
country = new Country("JPN","Japan",20000200);
countryList.add(country);
country = new Country("THA","Thailand",50000500);
countryList.add(country);
continent = new Continent("Asia",countryList);
continentList.add(continent);
}
@Override
public boolean onClose() {
listAdapter.filterData("");
expandAll();
return false;
}
@Override
public boolean onQueryTextChange(String query) {
listAdapter.filterData(query);
expandAll();
return false;
}
@Override
public boolean onQueryTextSubmit(String query) {
listAdapter.filterData(query);
expandAll();
return false;
}
}


2 comments:
how to get country name (string) or population from .setOnChildClickListener ?? thanks in advance!
about my question before: .setOnChildClickListener I already get solution, so I need to add:
continentList.get(groupPosition).getCountryList().get(childPosition).getName()
but now, I have another problem, when I use search function/filter, Why doesn't my ListView show the new data when I call notifyDataSetChanged ? pls help
Post a Comment
NO JUNK, Please try to keep this clean and related to the topic at hand.
Comments are for users to ask questions, collaborate or improve on existing.