46. ​​ExpandableListView Events

Lecture



In this lesson:

- we process events of the tree list

We are able to build a tree-list, now let's see how we can interact with it. We are given the opportunity to handle the following events: clicking on a group, clicking on an element, collapsing a group, expanding a group.

Let's create   project :

Project name : P0461_ExpandableListEvents
Build Target : Android 2.3.3
Application name : ExpandableListEvents
Package name : ru.startandroid.develop.p0461expandablelistevents
Create Activity : MainActivity

Screen main.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 = "fill_parent"
android: orientation = "vertical">
<LinearLayout
android: id = "@ + id / linearLayout1"
android: layout_width = "match_parent"
android: layout_height = "wrap_content"
android: orientation = "vertical">
<Textview
android: id = "@ + id / tvInfo"
android: layout_width = "wrap_content"
android: layout_height = "wrap_content">
</ TextView>
<ExpandableListView
android: id = "@ + id / elvMain"
android: layout_width = "match_parent"
android: layout_height = "wrap_content">
</ ExpandableListView>
</ LinearLayout>
</ LinearLayout>

TextView to display information and ExpandableListView .

In the project, next to the MainActivity class, we will create (not an Activity) the AdapterHelper class. Put the code in it to fill the list in order to unload MainActivity.java.

AdapterHelper.java code:

package ru.startandroid.develop.p0461expandablelistevents;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.widget.SimpleExpandableListAdapter;

public class AdapterHelper {

final String ATTR_GROUP_NAME= "groupName";
final String ATTR_PHONE_NAME= "phoneName";


// названия компаний (групп)
String[] groups = new String[] {"HTC", "Samsung", "LG"};

// названия телефонов (элементов)
String[] phonesHTC = new String[] {"Sensation", "Desire", "Wildfire", "Hero"};
String[] phonesSams = new String[] {"Galaxy S II", "Galaxy Nexus", "Wave"};
String[] phonesLG = new String[] {"Optimus", "Optimus Link", "Optimus Black", "Optimus One"};

// коллекция для групп
ArrayList<Map<String, String>> groupData;

// коллекция для элементов одной группы
ArrayList<Map<String, String>> childDataItem;

// общая коллекция для коллекций элементов
ArrayList<ArrayList<Map<String, String>>> childData;
// в итоге получится childData = ArrayList<childDataItem>

// список аттрибутов группы или элемента
Map<String, String> m;

Context ctx;

AdapterHelper(Context _ctx) {
ctx = _ctx;
}

SimpleExpandableListAdapter adapter;


SimpleExpandableListAdapter getAdapter() {

// заполняем коллекцию групп из массива с названиями групп
groupData = new ArrayList<Map<String, String>>();
for (String group : groups) {
// заполняем список аттрибутов для каждой группы
m = new HashMap<String, String>();
m.put(ATTR_GROUP_NAME, group); // имя компании
groupData.add(m);
}

// список аттрибутов групп для чтения
String groupFrom[] = new String[] {ATTR_GROUP_NAME};
// список ID view-элементов, в которые будет помещены аттрибуты групп
int groupTo[] = new int[] {android.R.id.text1};


// создаем коллекцию для коллекций элементов
childData = new ArrayList<ArrayList<Map<String, String>>>();

// создаем коллекцию элементов для первой группы
childDataItem = new ArrayList<Map<String, String>>();
// заполняем список аттрибутов для каждого элемента
for (String phone : phonesHTC) {
m = new HashMap<String, String>();
m.put(ATTR_PHONE_NAME, phone); // название телефона
childDataItem.add(m);
}
// добавляем в коллекцию коллекций
childData.add(childDataItem);

// создаем коллекцию элементов для второй группы
childDataItem = new ArrayList<Map<String, String>>();
for (String phone : phonesSams) {
m = new HashMap<String, String>();
m.put(ATTR_PHONE_NAME, phone);
childDataItem.add(m);
}
childData.add(childDataItem);

// создаем коллекцию элементов для третьей группы
childDataItem = new ArrayList<Map<String, String>>();
for (String phone : phonesLG) {
m = new HashMap<String, String>();
m.put(ATTR_PHONE_NAME, phone);
childDataItem.add(m);
}
childData.add(childDataItem);

// список аттрибутов элементов для чтения
String childFrom[] = new String[] {ATTR_PHONE_NAME};
// список ID view-элементов, в которые будет помещены аттрибуты элементов
int childTo[] = new int[] {android.R.id.text1};

adapter = new SimpleExpandableListAdapter(
ctx,
groupData,
android.R.layout.simple_expandable_list_item_1,
groupFrom,
groupTo,
childData,
android.R.layout.simple_list_item_1,
childFrom,
childTo);

return adapter;
}

String getGroupText(int groupPos) {
return ((Map<String,String>)(adapter.getGroup(groupPos))).get(ATTR_GROUP_NAME);
}

String getChildText(int groupPos, int childPos) {
return ((Map<String,String>)(adapter.getChild(groupPos, childPos))).get(ATTR_PHONE_NAME);
}

String getGroupChildText(int groupPos, int childPos) {
return getGroupText(groupPos) + " " + getChildText(groupPos, childPos);
}
}

The code for creating an adapter is completely borrowed from the last lesson. To get the adapter, we just need to call the getAdapter method.

The class has a constructor through which we give the object a link to the context . Context we need to create an adapter. The adapter, in turn, needs context, for example, to access the LayoutInflater.

At the end of the class are methods that return us the names of groups and elements from collections by group number or element number. To do this, use the getGroup and getChild adapter methods, bring them to the Map and retrieve the value of the attribute with the name of the company or phone.

We write the code in MainActivity.java :

package ru.startandroid.develop.p0461expandablelistevents;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.ExpandableListView.OnGroupCollapseListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;


public class MainActivity extends Activity {

final String LOG_TAG = "myLogs";

ExpandableListView elvMain;
AdapterHelper ah;
SimpleExpandableListAdapter adapter;
TextView tvInfo;

/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

tvInfo = (TextView) findViewById(R.id.tvInfo);

// создаем адаптер
ah = new AdapterHelper(this);
adapter = ah.getAdapter();

elvMain = (ExpandableListView) findViewById(R.id.elvMain);
elvMain.setAdapter(adapter);

// нажатие на элемент
elvMain.setOnChildClickListener(new OnChildClickListener() {
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
Log.d(LOG_TAG, "onChildClick groupPosition = " + groupPosition +
" childPosition = " + childPosition +
" id = " + id);
tvInfo.setText(ah.getGroupChildText(groupPosition, childPosition));
return false;
}
});

// нажатие на группу
elvMain.setOnGroupClickListener(new OnGroupClickListener() {
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
Log.d(LOG_TAG, "onGroupClick groupPosition = " + groupPosition +
" id = " + id);
// блокируем дальнейшую обработку события для группы с позицией 1
if (groupPosition == 1) return true;

return false;
}
});

// сворачивание группы
elvMain.setOnGroupCollapseListener(new OnGroupCollapseListener() {
public void onGroupCollapse(int groupPosition) {
Log.d(LOG_TAG, "onGroupCollapse groupPosition = " + groupPosition);
tvInfo.setText("Свернули " + ah.getGroupText(groupPosition));
}
});

// разворачивание группы
elvMain.setOnGroupExpandListener(new OnGroupExpandListener() {
public void onGroupExpand(int groupPosition) {
Log.d(LOG_TAG, "onGroupExpand groupPosition = " + groupPosition);
tvInfo.setText("Равзвернули " + ah.getGroupText(groupPosition));
}
});

// разворачиваем группу с позицией 2
elvMain.expandGroup(2);
}
}

Thanks to the AdapterHelper class, the adapter creation code took only two lines: the creation of an object and a call to the getAdapter method. Next, assign the adapter to the list and add handlers :

1) OnChildClickListener - click on the item

Method
public boolean onChildClick (ExpandableListView parent, View v, int groupPosition, int childPosition, long id), where

parent - ExpandableListView with which we work
v - View element
groupPosition - group position in the list
childPosition - the position of the element in the group
id - element id

We log the position and id. And in the TextView at the top of the list, we display the text of the clicked element and its group , which we obtain using the AdapterHelper methods.

The method should return boolean . If we return true - it means, we inform that we ourselves have fully processed the event and it will not go to further event handlers (if any). Returning false means we allow the event to go further .

2) OnGroupClickListener - clicking on a group

Method
public boolean onGroupClick (ExpandableListView parent, View v, int groupPosition, long id), where

parent - ExpandableListView with which we work
v - View element
groupPosition - group position in the list
id - group id

We log the position and id of the group.

This method should also return boolean . We will return true if the position of the group = 1, otherwise - false. Those. for this group, we block further event handling. Further we will see that it will give us.

3) OnGroupCollapseListener - folding group

Method
onGroupCollapse (int groupPosition), where groupPosition is the position of the group that is collapsed

4) OnGroupExpandListener - group deployment

Method
onGroupExpand (int groupPosition), where groupPosition is the position of the group that has been expanded

And at the end of the MainActivity code, we expand the group with position 2 using the expandGroup method.

All save and run.

As you can see, the LG group is immediately deployed. This worked for the expandGroup command at the end of the code.

If you look in the log, we see

onGroupExpand groupPosition = 2

Those. fulfilled the event of expanding the group with position 2.

Click, for example, on Optimus Link. We look at the log:

onChildClick groupPosition = 2 childPosition = 1 id = 1

Do not forget that the position is considered from scratch. Group with position 2 - LG, element with position 1 - Optimus Link, that's right.

We look at the TextView at the top of the screen, it read the attribute value from the adapter and displayed it.

Now let's try to minimize the LG group, click on it. We look at the log:

onGroupClick groupPosition = 2 id = 2
onGroupCollapse groupPosition = 2

First worked onGroupClick - clicking on the group, and then onGroupCollapse - folding the group. TextView at the top of the screen announced that the LG group had collapsed.

Expand the LG group again. Log:

onGroupClick groupPosition = 2 id = 2
onGroupExpand groupPosition = 2

Clicking on a group and unfolding. Please note that during software deployment, there was no push event, only a reversal.

Now let's try to expand the group with position 1 - Samsung. The group does not unfold. We look at the log:

onGroupClick   groupPosition = 1 id = 1

There is a push event, but the deployment handler is not called. This is because of the line

// блокируем дальнейшую обработку события для группы с позицией 1
if (groupPosition == 1) return true;

For the group with position 1, we block further event handling and it does not go to the expand or collapse handlers. Therefore, onGroupExpand does not work.

As a result, these 4 handlers allow you to determine how the user interacts with the tree.


Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Mobile Programming (Android IOs)

Terms: Mobile Programming (Android IOs)