How to create a custom ExpandableListView

Here I will show you how to create a custom ExpandableListView, how to use your own fonts and how to inflate a custom layout from xml

The expandable Listview has at least two levels. When you click on a parent list item, the child items will be shown.

If you want to find out more about ExpandableListView you can check here.

Here is the result:

First of all create an android project in Eclipse as usual.
you can replace the main.xml code by this one:

<?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="fill_parent">
    <ExpandableListView android:layout_height="wrap_content"
    android:layout_weight="1"
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:groupIndicator="@drawable/icon"
    android:divider="@null"></ExpandableListView>
</LinearLayout>

this line is very important other wise you will get errors:
android:id=”@android:id/list”

then you can setup an icon to be used in front of all the parent entries, instead of the default arrow:
android:groupIndicator=”@drawable/icon”

you can replace it with:
android:groupIndicator=”@drawable/icon”
and you will then get no icon

with this code I specify that I don’t want any separators:
android:divider=”@null”

Here is the code for the our class:

public class ExpandableListExample extends ExpandableListActivity {

private MyExpandableListAdapter mAdapter;
private String[] preguntas;
private String[][] respuestas;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);

// getting the arrays from the ressources

// group array
preguntas = getResources().getStringArray(R.array.countries);

// children array
String[] respuestas1 = getResources().getStringArray(R.array.capitals);
respuestas = new String[respuestas1.length][1];
for (int i = 0; i < respuestas1.length; i++) {
respuestas[i][0] = respuestas1[i];
}

// Set up our adapter
mAdapter = new MyExpandableListAdapter();
setListAdapter(mAdapter);
}

You will need to set up 2 string arrays in the string.xml file.

And here is the adapter class for our list, you just add it below the other code:

public class MyExpandableListAdapter extends BaseExpandableListAdapter {

        public Object getChild(int groupPosition, int childPosition) {
            return respuestas[groupPosition][childPosition];
        }

        public long getChildId(int groupPosition, int childPosition) {
            return childPosition;
        }

        public int getChildrenCount(int groupPosition) {
            return respuestas[groupPosition].length;
        }

        public TextView getGenericView() {
            // Layout parameters for the ExpandableListView
            AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
                    ViewGroup.LayoutParams.FILL_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);

            TextView textView = new TextView(ExpandableListExample.this);

            textView.setLayoutParams(lp);

            textView.setPadding(60, 5, 0, 5);
            textView.setTextAppearance(getBaseContext(), R.style.TitleText);
            return textView;
        }

        public View getChildView(int groupPosition, int childPosition,
                boolean isLastChild, View convertView, ViewGroup parent) {

            //Including a custom view for the child image and text
            View inflatedView = View.inflate(getApplicationContext(),
                    R.layout.child, null);
            inflatedView.setPadding(50, 0, 0, 0);
            TextView textView =(TextView)inflatedView.findViewById(R.id.textView1);

            //lets set up a custom font
            Typeface font = Typeface.createFromAsset(getAssets(),"BLOODY.ttf");
            textView.setTypeface(font);
            textView.setTextSize(17);
            textView.setText(getChild(groupPosition, childPosition).toString());
            return inflatedView;
        }

        public Object getGroup(int groupPosition) {
            return preguntas[groupPosition];
        }

        public int getGroupCount() {
            return preguntas.length;
        }

        public long getGroupId(int groupPosition) {
            return groupPosition;
        }

        public View getGroupView(int groupPosition, boolean isExpanded,
                View convertView, ViewGroup parent) {
            TextView textView = getGenericView();
            textView.setText(getGroup(groupPosition).toString());
            return textView;
        }

        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }

        public boolean hasStableIds() {
            return true;
        }

    }

You can get a font here.

Download it and then place the .ttf file in the asset folder of you project (it already exists you don’t have to create it).

As you can see i have cerated a custom style for the parent textView, I included it in the values/styles.xml file. Inside this file you can set up all kinds of attributes for your layouts, like text color, size etc..

And finally here is the custom layout for the childviews:

<?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="wrap_content">
    <ImageView android:layout_width="wrap_content"
    android:id="@+id/imageView1"
    android:src="@drawable/icon2"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"></ImageView>
    <TextView android:text="TextView"
    android:layout_width="wrap_content"
    android:id="@+id/textView1"
    android:layout_gravity="center_horizontal"
    android:layout_height="fill_parent"
    android:gravity="center_vertical"></TextView>
  </LinearLayout>

I hope this helps you!

you can download the full source here:

About these ads