Lesson 46. ExpandableListView Events


In this lesson:

– handle list tree events

We know how to build a list tree, now let’s see how you can interact with it. We have the ability to handle the following events: clicking on a group, clicking on an item, minimizing a group, expanding a group.

let’s create project:

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

screen main.xml:



    
        
        
        
        
    

TextView to output information and ExpandableListView.

In the project, next to the class MainActivity let’s create an (NOT Activity) class AdapterHelper. We’ll put the code to populate the list to unload MainActivity.java.

code AdapterHelper.java:

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> groupData;
  
  // коллекция для элементов одной группы
  ArrayList> childDataItem;

  // общая коллекция для коллекций элементов
  ArrayList>> childData;
  // в итоге получится childData = ArrayList
  
  // список аттрибутов группы или элемента
  Map m;
  
  Context ctx;
  
  AdapterHelper(Context _ctx) {
    ctx = _ctx;
  }
  
  SimpleExpandableListAdapter adapter;
  
  
  SimpleExpandableListAdapter getAdapter() {
    
    // заполняем коллекцию групп из массива с названиями групп
        groupData = new ArrayList>();
        for (String group : groups) {
          // заполняем список аттрибутов для каждой группы
          m = new HashMap();
            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>>(); 
        
        // создаем коллекцию элементов для первой группы
        childDataItem = new ArrayList>();
        // заполняем список аттрибутов для каждого элемента
        for (String phone : phonesHTC) {
          m = new HashMap();
            m.put(ATTR_PHONE_NAME, phone); // название телефона
            childDataItem.add(m);  
        }
        // добавляем в коллекцию коллекций
        childData.add(childDataItem);

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

        // создаем коллекцию элементов для третьей группы        
        childDataItem = new ArrayList>();
        for (String phone : phonesLG) {
          m = new HashMap();
            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)(adapter.getGroup(groupPos))).get(ATTR_GROUP_NAME);
  }
  
  String getChildText(int groupPos, int childPos) {
    return ((Map)(adapter.getChild(groupPos, childPos))).get(ATTR_PHONE_NAME);
  }
  
  String getGroupChildText(int groupPos, int childPos) {
    return getGroupText(groupPos) + " " +  getChildText(groupPos, childPos);
  }
}

The adapter creation code is completely borrowed from the last lesson. To get the adapter we will just have to call the method getAdapter.

The class has designerThrough which we pass the object a link to context. We need context to create an adapter. The context adapter, for example, is required, for example, to access LayoutInflater.

At the end of the class are methods that return us the names of groups and items from collections by group number or item number. To do this, we use the adapter methods getGroup and getChildWe bring them to Map and extract the value attribute with your business or phone name.

We write 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 class AdapterHelper, The adapter creation code took only two lines: creature object and method call getAdapter. Next, we assign a list adapter and add handlers:

1) OnChildClickListener – clicking on an item

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

parent – ExpandableListView we work with
v – View item
groupPosition – the group’s position in the list
childPosition – the position of the item in the group
id – element id

We log the position and id. And in TextView output from the list text pressed items and him groupsObtained using AdapterHelper methods.

The method must return boolean. If we return true – that is, we inform ourselves that we are completely handled the event and it is will not go into further handlers (if any). if we return false – so we allow events go further.

2) OnGroupClickListener – clicking on a group

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

parent – ExpandableListView we work with
v – View item
groupPosition – the group’s position in the list
id – group id

We display the position and id of the group.

This method should also return boolean. We will return true if group position = 1, otherwise false. That is, we block further event processing for this group. Next we will see what it will give us.

3) OnGroupCollapseListener – minimize the group

method
onGroupCollapse(Int groupPosition), where groupPosition is the position of the group that was collapsed

4) OnGroupExpandListener – Group Deployment

method
onGroupExpand(Int groupPosition), where groupPosition is the position of the group that was expanded

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

We will save everything and run it.

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

If you look in the log, we see

onGroupExpand groupPosition = 2

That is, a Group 2 deployment event has worked.

For example, click 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 2 – LG, Element 1 – Optimus Link, that’s right.

Looking at TextView from above, he considered the value of the attribute from the adapter and displayed it.

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

onGroupClick groupPosition = 2 id = 2
onGroupCollapse groupPosition = 2

first worked out onGroupClick – clicking on a group and then onGroupCollapse – group folding. TextView at the top of the screen announced that they had rolled up the LG group.

Let’s deploy the LG group again. log:

onGroupClick groupPosition = 2 id = 2
onGroupExpand groupPosition = 2

Clicking on a group and expanding. Note that during program deployment, there was no click event, only a reversal.

Now let’s try to expand the group with position 1 – Samsung. The band is not expanding. We look at the log:

onGroupClick groupPosition = 1 id = 1

There is a click event, but the deployment handler is not called. This happens through rows

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

For Group 1, we block further event processing and it does not go to deployment or collapse handlers. That’s why it doesn’t work onGroupExpand.

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




Discuss in the forum [80 replies]

Leave a Comment