45. ExpandableListView tree list

Lecture



In this lesson:

- build an ExpandableListView tree list

If the list of elements is large, it makes sense to divide it into groups to simplify navigation. For these purposes, you can use the ExpandableListView. This is a list in the form of a two-level tree. The first level is a group , and in it the second is an element .

To build such a list, we need to somehow transfer the data to the adapter by groups and elements.

Each group is a Map . This Map contains the attributes you need for each group. Then all these Map (groups) are collected in a List- collection , for example ArrayList. As a result, we received groups packed into one object.

Each element of the group is also represented by a Map Object. We collect all the Map (elements) for each group in a separate collection . It turns out that each group has a collection with elements. Further we now place these collections in the general collection. Those. the result is a two-dimensional array. And as a result, the items are packed in one object.

Now we will begin to code an example and there it will become more clear.

List collections are usually called “lists”. But since The list in the context of the last lesson is a set of items on the screen (ListView), so as not to be confused, I will use the word “collection”.

Create a project:

Project name : P0451_ExpandableList
Build Target : Android 2.3.3
Application name : ExpandableList
Package name : ru.startandroid.develop.p0451expandablelist
Create Activity : MainActivity

Let's draw the main.xml screen:

   
    xmlns: android = "http://schemas.android.com/apk/res/android" 
  android: layout_width = "fill_parent" 
  android: layout_height = "fill_parent" 
  android: orientation = "vertical"> 
    android: id = "@ + id / elvMain" 
  android: layout_width = "match_parent" 
  android: layout_height = "wrap_content"> 
   
   

Only ExpandableList on the screen.

MainActivity.java code:

package ru.startandroid.develop.p0451expandablelist;

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

import android.app.Activity;
import android.os.Bundle;
import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter;

public class MainActivity extends Activity {

// названия компаний (групп)
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;

ExpandableListView elvMain;


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

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

// список аттрибутов групп для чтения
String groupFrom[] = new String[] {"groupName"};
// список 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("phoneName", phone); // название телефона
childDataItem.add(m);
}
// добавляем в коллекцию коллекций
childData.add(childDataItem);

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

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

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

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

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

The code is bulky and complicated, let's understand.

First, in the class we describe the data arrays - these are the names of the groups and the names of the elements for them. I decided to choose smartphones as data. The groups on our list will be companies , and the elements will be the smartphones of these companies.

Then we describe the collection for groups, the collections for the elements and the Map for the attributes.

In the onCreate method, fill in the groupData . This is a collection of groups. Each group is a Map . And in the Map we write the attributes we need for each group. In our case, for each group, we specify only one attribute groupName - this is the name of the company from the groups array.

As we remember, the adapter usually uses a layout resource to display a list item. In our case, the items in the ListView are both the group and the item . There can be any TextView in the layout resource. We can fill them with values ​​from the attributes of the elements or groups that are collected in the Map. To do this, we must first specify the names of the attributes that we want to use, and then the ID TextView elements, in which we want to put the values ​​of these attributes. We are now talking about text attributes. (Although generally the attribute is not required to be a class String)

To bundle attributes and TextView elements, we use two arrays:

groupFrom is a list of attribute names to be read. In our case, this is the groupName , which we added to the group using the Map a little higher in the code when we collected groups in groupData.
groupTo - the list of ID View-elements in which the read attribute values ​​will be placed. Our used layout will contain a TextView with ID = android.R.id.text1 .

These two arrays are matched in order of elements. As a result, in the group's layout- resource there is an element with ID = android.R.id.text1 and the text from the groupName attribute is written to it . Thus, we get the display of the name of the group (company) in the list.

Next, create a collection of elements . Create a shared collection of collections . And then we create collections of elements of each group. The principle is the same as with groups - we create a Map and write the attribute phoneName to it with a value equal to the name of the element (phone). The collection of elements for each group is added to the general collection.

We form two arrays for matching the TextView from the layout and attributes of the elements. Completely similar, as above, we have already done with the groups. As a result, when displaying an element, there will be a TextView with ID = android.R.id.text1 and the text from the phoneName attribute will be written there. And we will see the text of our element (phone) in the list.

At the end of the code, we create a SimpleExpandableListAdapter adapter and assign it to the list.

At the entrance when creating the adapter are the elements:

this - context
groupData - collection of groups
android.R.layout.simple_expandable_list_item_1 is a layout resource that will be used to display the group in the list. Accordingly, you can easily use your layout file.
groupFrom - an array of group attribute names
groupTo - an array of TextView ID from layout for groups
childData - collection of element collections by groups
android.R.layout.simple_list_item_1 is a layout resource that will be used to display an item in the list. You can use your layout file
childFrom - an array of element attribute names
childTo is an array of TextView IDs from layout for elements.

In general, the implementation of the tree is not easy, in my opinion. Perhaps not immediately get to understand. But I tried to paint everything thoroughly and as detailed as possible.

Layout simple_expandable_list_item_1 , which we used to display groups - this TextView is indented from the left edge, so that there is room for the expand / collapse button of the list. For the experiment, you can try using for the groups the layout simple_list_item_1 , which we used for the elements. In this case, the text will overlap with the button.

In general, you can create for your elements your layout , for example, with three TextView . And to each element of the list (Map) add two more attributes: price and color. Next, specify your layout in the constructor, form the childFrom and childTo arrays respectively to match the attributes and the TextView, and it turns out that each element of the group contains more detailed information about the smartphone.

In the next lesson:

- we process events of the tree list

avatar
28.4.2020 8:18

попробовал поэкспериментировать с настройками
adapter, в частности с android.R.id.text1 (подставил android.R.id.text2, собственные настройки),
получил один результат - пропал вывод на экран массива фирм (самсунг и т.д.).
Подскажите, в чем проблема.

в инете нашел описание android.R.id.text1, подставил, тот же результат, не работает.

TextView
android:id= @android:id/text1
android:layout_width= fill_parent
android:layout_height= ?android:attr/listPreferredItemHeight
android:textAppearance= ?android:attr/textAppearanceLarge
android:gravity= center_vertical
android:paddingLeft= 5dip
android:singleLine= true
/

avatar
28.4.2020 8:18

Походу вы указываете адаптеру поля, которых нет в layout.

Укажите здесь вашу строку создания адаптера, плз. Чтобы было видно, какие layout используются. И содержимое массивов groupTo и childTo.

avatar
28.4.2020 8:19

В тексте ничего не менял.
Я хотел по экспериментировать с шаблонами гугла.
в строке
int groupTo = new int android.R.id.text1 ;
Заменил один шаблон на другой.
int groupTo = new int android.R.id.text2 ;
Подставил в файл компановки main.xml свои настройки.
Результат один, пропадают названия фирм.


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)