Создаем выпадающий список Expandable ListView
Главная » Создаем выпадающий список Expandable ListView

Вы уже имели возможность разобраться с основами работы с элементом ListView в предыдущем уроке, в котором мы создавали обычный стандартный список, а также создавали ему желаемый внешний вид. В сегодняшнем уроке мы продолжим работу со списками в Android программировании и научимся делать выпадающий, или расширяющийся список Expandable ListView, то есть такой, в котором при нажатии на пункты меню будут появляться дополнительные подпункты.

Начнем с того, что создадим новый проект, все названия оставим по умолчанию, выбираем Blank Activity. Для того, чтобы создать расширяемый список, нам в дальнейшем понадобиться 3 xml layout файла. Но все по порядку.

Открываем главный xml файл activity_main.xml и добавляем в нем элемент Expandable ListView:

<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"
 tools:context=".MainActivity">
 <ExpandableListView
 android:id="@+id/lvExp"
 android:layout_height="match_parent"
 android:layout_width="match_parent"/>
</RelativeLayout>

Создадим новый файл xml в котором будет содержаться заголовок нашего будущего Expandable ListView. В папке res/layout создаем файл по имени list_group.xml и добавляем в него элемент TextView:

<?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"
 android:orientation="vertical"
 android:padding="8dp"
 android:background="#000000">
 <TextView
 android:id="@+id/lblListHeader"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
 android:textSize="17dp"
 android:textColor="#f9f93d" />
</LinearLayout>

Теперь создаем еще один xml файл list_item.xml и добавим туда следующий код:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="55dip"
 android:orientation="vertical" >
 <TextView
 android:id="@+id/lblListItem"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:textSize="17dip"
 android:paddingTop="5dp"
 android:paddingBottom="5dp"
 android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft" />
</LinearLayout>

Теперь нам нужно создать новый java класс, который будет расширяться от BaseExpandableListAdapter и тем самым облегчит нашу задачу по работе с ListView. Также в нем сразу будут необходимые для работы методы getGroupView и getChildView, необходимые для настройки вида заголовка и подпунктов. Итак, создаем новый класс по имени ExpandableListAdapter.java и запихиваем в него следующий код:

import java.util.HashMap;
import java.util.List;
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

public class ExpandableListAdapter extends BaseExpandableListAdapter {

 private Context _context;
 //Названия заголовков
 private List<String> _listDataHeader; 
 //Данные для элементов подпунктов:
 private HashMap<String, List<String>> _listDataChild;

 public ExpandableListAdapter(Context context, List<String> listDataHeader,
 HashMap<String, List<String>> listChildData) {
 this._context = context;
 this._listDataHeader = listDataHeader;
 this._listDataChild = listChildData;
 }

 @Override
 public Object getChild(int groupPosition, int childPosititon) {
 return this._listDataChild.get(this._listDataHeader.get(groupPosition))
 .get(childPosititon);
 }

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

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

 final String childText = (String) getChild(groupPosition, childPosition);

 if (convertView == null) {
 LayoutInflater infalInflater = (LayoutInflater) this._context
 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 convertView = infalInflater.inflate(R.layout.list_item, null);
 }

 TextView txtListChild = (TextView) convertView
 .findViewById(R.id.lblListItem);

 txtListChild.setText(childText);
 return convertView;
 }

 @Override
 public int getChildrenCount(int groupPosition) {
 return this._listDataChild.get(this._listDataHeader.get(groupPosition))
 .size();
 }

 @Override
 public Object getGroup(int groupPosition) {
 return this._listDataHeader.get(groupPosition);
 }

 @Override
 public int getGroupCount() {
 return this._listDataHeader.size();
 }

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

 @Override
 public View getGroupView(int groupPosition, boolean isExpanded,
 View convertView, ViewGroup parent) {
 String headerTitle = (String) getGroup(groupPosition);
 if (convertView == null) {
 LayoutInflater infalInflater = (LayoutInflater) this._context
 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 convertView = infalInflater.inflate(R.layout.list_group, null);
 }

 TextView lblListHeader = (TextView) convertView
 .findViewById(R.id.lblListHeader);
 lblListHeader.setTypeface(null, Typeface.BOLD);
 lblListHeader.setText(headerTitle);

 return convertView;
 }

 @Override
 public boolean hasStableIds() {
 return false;
 }

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

Таким образом мы настроили адаптер для работы всех необходимых элементов нашего Expandable ListView. Теперь откроем MainActivity.java класс и добавим туда следующие изменения. Здесь мы создадим необходимые для списка данные и свяжем их с созданным выше адаптером:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
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.Toast;

public class MainActivity extends Activity {

 ExpandableListAdapter listAdapter;
 ExpandableListView expListView;
 List<String> listDataHeader;
 HashMap<String, List<String>> listDataChild;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 //Связываемся с нашим ExpandableListView:
 expListView = (ExpandableListView) findViewById(R.id.lvExp);

 //Подготавливаем список данных:
 prepareListData();

 listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);

 //Настраиваем listAdapter:
 expListView.setAdapter(listAdapter);
 }

 /*
 * Подготавливаем данные для списка:
 */
 private void prepareListData() {
 listDataHeader = new ArrayList<String>();
 listDataChild = new HashMap<String, List<String>>();

 //Добавляем данные о пунктах списка:
 listDataHeader.add("Пункт 1");
 listDataHeader.add("Пункт 2");
 listDataHeader.add("Пункт 3");

 //Добавляем данные о подпунктах:
 List<String> top250 = new ArrayList<String>();
 top250.add("Подпункт 1.1");
 top250.add("Подпункт 1.2");
 top250.add("Подпункт 1.3");
 top250.add("Подпункт 1.4");
 top250.add("Подпункт 1.5");
 top250.add("Подпункт 1.6");
 top250.add("Подпункт 1.7");

 List<String> nowShowing = new ArrayList<String>();
 nowShowing.add("Подпункт 2.1");
 nowShowing.add("Подпункт 2.2");
 nowShowing.add("Подпункт 2.3");
 nowShowing.add("Подпункт 2.4");
 nowShowing.add("Подпункт 2.5");
 nowShowing.add("Подпункт 2.6");

 List<String> comingSoon = new ArrayList<String>();
 comingSoon.add("Подпункт 3.1");
 comingSoon.add("Подпункт 3.2");
 comingSoon.add("Подпункт 3.3");
 comingSoon.add("Подпункт 3.4");
 comingSoon.add("Подпункт 3.5");

 listDataChild.put(listDataHeader.get(0), top250);
 listDataChild.put(listDataHeader.get(1), nowShowing);
 listDataChild.put(listDataHeader.get(2), comingSoon);
 }
}

Может запустить то, что сотворили и посмотреть на результат:

Запускаем расширенный список

Программа работает, список функционирует и показывает подпункты. Но подпункты никак не реагируют на нажатия и по желанию это можно исправить. Для этого нужно добавить приложению выполнение интерфейса setOnChildClickListener, который будет отображать Toast сообщение с информацией о манипуляциях с пунктами и подпунктами меню. Выполняем setOnChildClickListener:

expListView.setOnChildClickListener(new OnChildClickListener() {
 
 @Override
 public boolean onChildClick(ExpandableListView parent, View v,
 int groupPosition, int childPosition, long id) {
 Toast.makeText(
 getApplicationContext(),
 listDataHeader.get(groupPosition)
 + " : "
 + listDataChild.get(
 listDataHeader.get(groupPosition)).get(
 childPosition), Toast.LENGTH_SHORT)
 .show();
 return false;
 }
 });

Установим еще такие функции слушателя, чтобы они показывали нам сообщение о том, что список раскрыт или закрыт, когда это происходит. Для раскрытия списка используем метод:

//При раскрывании списка
expListView.setOnGroupExpandListener(new OnGroupExpandListener() {
 
 @Override
 public void onGroupExpand(int groupPosition) {
 Toast.makeText(getApplicationContext(),
 listDataHeader.get(groupPosition) + " Раскрыт",
 Toast.LENGTH_SHORT).show();
 }
});

Ну и напоследок добавим метод работы слушателя при сворачивании списка:

//Сворачиваем список
expListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
 
 @Override
 public void onGroupCollapse(int groupPosition) {
 Toast.makeText(getApplicationContext(),
 listDataHeader.get(groupPosition) + " Свернут",
 Toast.LENGTH_SHORT).show();
 
 }
});

Ну вот теперь все! Запускаем и смотрим, что же у нас получилось:

Полностью готовая программа

Для тех, у кого что то не вышло и возникла путаница в коде, вот полный код файла MainActivity.java.

Категория: Уроки программирования | Просмотров: 1286 | Добавил: Oleg | Теги: расширяемый ListView, Список, выпадающий список, ListView, Expandable ListView | Рейтинг: 0.0/0
Всего комментариев: 0
avatar