LoginSignup
40
41

More than 5 years have passed since last update.

Androidで折りたたみ式リストビューを使うメモ【ExpandableListView】

Posted at

Androidで折りたたみ式リストビュー(ExpandableListView)を使う方法をメモします。

ExpandableListViewを持ったレイアウト

レイアウトの設定

まず、ExpandalbeListViewを持ったレイアウトを作成します。
レイアウトに ExpandableListView をドロップし下記のようにします。

activity_main.xml
<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <ExpandableListView
        android:id="@+id/expandableListView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="14dp" >
    </ExpandableListView>

</RelativeLayout>

ExpandableListViewを使用したActivity

次に、Activityを作成します。
ExpandableListViewで情報を表示するには、SimpleExpandableListAdapterを使います。
SimpleExpandableListAdapterを使用することで、簡単にExpandableListViewへデータを渡すことができます。
リストとして表示したい情報をSimpleExpandableListAdapterへ格納するため、下記の順にMapを作成します。

  1. グループの親項目用のリストを作る
  2. リスト項目として表示したい子要素全体用のリストを作る
  3. グループの親項目用のMapに情報を格納する
  4. 各グループ別のリスト項目用のリストを作る
  5. 各グループ別のリスト項目用のMapに情報を格納する
  6. 子要素全体用のリストに、各グループ別のリスト項目用リストを格納する
  7. グループの親項目用のリストと、子要素全体用のリストをSimpleExpandableListAdapterへ格納する

では、実際にコードにします。

各データの格納

まず、グループの親項目用のMapに、表示したい内容を格納します。

MainActivity.java
int PARENT_DATA = 3;
// グループの親項目用のリスト
List<Map<String, String>> parentList = new ArrayList<Map<String, String>>();
// 親リストに表示する内容を生成
for (int i = 0; i < PARENT_DATA; i++) {
    Map<String, String> parentData = new HashMap<String, String>();
    parentData.put("title", "title" + Integer.toString(i));
    // グループの親項目用のリストに内容を格納
    parentList.add(parentData);
}

次に、子要素となる内容を格納します。

MainActivity.java
int CHILD_DATA = 3;
// 子要素全体用のリスト
List<List<Map<String, String>>> allChildList = new ArrayList<List<Map<String, String>>>();

// 子要素として表示する文字を生成
for (int i = 0; i < PARENT_DATA; i++) {
    // 各グループ別のリスト項目用のリスト
    List<Map<String, String>> childList = new ArrayList<Map<String, String>>();

    // リスト項目用データ格納
    for (int j = 0; j < CHILD_DATA; j++) {
        Map<String, String> childData = new HashMap<String, String>();
        childData.put("TITLE", "子要素" + Integer.toString(j));
        childData.put("SUMMARY", "概要" + Integer.toString(j));
        // リストに文字を格納
        childList.add(childData);
    }
    // 子要素全体用のリストに各グループごとデータを格納
    allChildList.add(childList);
}

アダプタに格納

そして、作成した情報をアダプターに格納します。

MainActivity.java
// アダプタを作る
SimpleExpandableListAdapter adapter =
        new SimpleExpandableListAdapter(
                this,
                parentList,
                android.R.layout.simple_expandable_list_item_1,
                new String[] { KEY1 },
                new int[] { android.R.id.text1, android.R.id.text2 },
                allChildList,
                android.R.layout.simple_expandable_list_item_2,
                new String[] { KEY1, KEY2 },
                new int[] { android.R.id.text1, android.R.id.text2 }
);
//生成した情報をセット
ExpandableListView lv = (ExpandableListView)findViewById(R.id.expandableListView1);
lv.setAdapter(adapter);

なお、SimpleExpandableListAdapterクラスのコンストラクタは下記のようになっています。

引数 変数 説明
1 Context context ExpandableListViewが関連付けられるContext
2 List< ? extends Map> groupData Group(親)のリスト
3 int expandedGroupLayout Group(親)のレイアウト
4 String[] groupFrom Group(親)のリストで表示するMapのキー
5 int[] groupTo Group(親)のレイアウト内での文字を表示するTextViewのID
6 List< ? extends List< ? extends Map< String, ?>>> Child(子)のリスト
7 int childLayout Child(子)のレイアウト
8 String[] childFrom Child(子)のリストで表示するMapのキー
9 int[] childTo Child(子)のレイアウト内での文字を表示するTextViewのID

リストの項目がクリックされた時の処理

リストの項目がクリックされた時の処理を作るには、OnChildClickListenerインターフェースのonChildClickメソッドを使います。

MainActivity.java
// リスト項目がクリックされた時の処理
lv.setOnChildClickListener(new OnChildClickListener() {
    @Override
    public boolean onChildClick(ExpandableListView parent, View view,
            int groupPosition, int childPosition, long id) {
        ExpandableListAdapter adapter = parent.getExpandableListAdapter();
        // クリックされた場所の内容情報を取得
        @SuppressWarnings("unchecked")
        Map<String, String> item = (Map<String, String>)adapter.getChild(groupPosition, childPosition);
        // アラート表示
        AlertDialog.Builder dlg = new AlertDialog.Builder(MainActivity.this);
        dlg.setTitle("クリック!")
        .setMessage(item.get(KEY1))
        .setPositiveButton("OK", null)
        .show();

        return false;
    }
});

onChildClickメソッドの引数は下記のようになっています。

引数 変数 説明
1 ExpandableListView parent イベントが起きたExpandableListView
2 View view 選択されたリスト項目
3 int groupPosition 選択されたリスト項目の親グループの位置(0~)
4 int childPosition 選択されたリスト項目の、グループ内での位置(0~)
5 long id 選択されたリスト項目のIDを示す値(0~)

グループの親項目がクリックされた時の処理

グループの親項目が選択された時の処理を作るには、OnGroupClickListenerインターフェースのonGroupClickメソッドを使います。

MainActivity.java
// グループの親項目がクリックされた時の処理
lv.setOnGroupClickListener(new OnGroupClickListener() {
    @Override
    public boolean onGroupClick(ExpandableListView parent, View view,
            int groupPosition, long id) {
        ExpandableListAdapter adapter = parent.getExpandableListAdapter();
        // クリックされた場所の内容情報を取得
        @SuppressWarnings("unchecked")
        Map<String, String> item = (Map<String, String>)adapter.getGroup(groupPosition);
        // アラート表示
        AlertDialog.Builder dlg = new AlertDialog.Builder(MainActivity.this);
        dlg.setTitle("クリック!")
        .setMessage(item.get(KEY1))
        .setPositiveButton("OK", null)
        .show();

        return false;
    }
});

onGroupClickメソッドの引数は下記のようになっています。

引数 変数 説明
1 ExpandableListView parent イベントが起きたExpandableListView
2 View view 選択されたグループの親項目
3 int groupPosition 選択されたグループの親項目の位置(0~)
4 long id 選択されたグループの親項目のIDを示す値(0〜)

完成ソース

上記の処理をまとめると、下記のようなソースになります。

MainActivity.java
package com.yuuweb.expandablelistviewtest;

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

import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.SimpleExpandableListAdapter;
import android.app.Activity;
import android.app.AlertDialog;

public class MainActivity extends Activity {

    private final String KEY1 = "TITLE";
    private final String KEY2 = "SUMMARY";

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

        int PARENT_DATA = 3;
        // 親ノードのリスト
        List<Map<String, String>> parentList = new ArrayList<Map<String, String>>();
        // 親ノードに表示する内容を生成
        for (int i = 0; i < PARENT_DATA; i++) {
            Map<String, String> parentData = new HashMap<String, String>();
            parentData.put(KEY1, "タイトル" + Integer.toString(i));
            // 親ノードのリストに内容を格納
            parentList.add(parentData);
        }

        int CHILD_DATA = 3;
        // 全体の子ノードのリスト
        List<List<Map<String, String>>> allChildList = new ArrayList<List<Map<String, String>>>();

        // 子要素として表示する文字を生成
        for (int i = 0; i < PARENT_DATA; i++) {
            // 子要素全体用のリスト
            List<Map<String, String>> childList = new ArrayList<Map<String, String>>();

            // 各子ノード用データ格納
            for (int j = 0; j < CHILD_DATA; j++) {
                Map<String, String> childData = new HashMap<String, String>();
                childData.put(KEY1, "子要素" + Integer.toString(j));
                childData.put(KEY2, "概要" + Integer.toString(j));
                // 子ノードのリストに文字を格納
                childList.add(childData);
            }
            // 全体の子ノードリストに各小ノードリストのデータを格納
            allChildList.add(childList);
        }

        // アダプタを作る
        SimpleExpandableListAdapter adapter =
                new SimpleExpandableListAdapter(
                        this,
                        parentList,
                        android.R.layout.simple_expandable_list_item_1,
                        new String[] { KEY1 },
                        new int[] { android.R.id.text1, android.R.id.text2 },
                        allChildList,
                        android.R.layout.simple_expandable_list_item_2,
                        new String[] { KEY1, KEY2 },
                        new int[] { android.R.id.text1, android.R.id.text2 }
        );
        //生成した情報をセット
        ExpandableListView lv = (ExpandableListView)findViewById(R.id.expandableListView1);
        lv.setAdapter(adapter);

        // リスト項目がクリックされた時の処理
        lv.setOnChildClickListener(new OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View view,
                    int groupPosition, int childPosition, long id) {
                ExpandableListAdapter adapter = parent.getExpandableListAdapter();
                // クリックされた場所の内容情報を取得
                @SuppressWarnings("unchecked")
                Map<String, String> item = (Map<String, String>)adapter.getChild(groupPosition, childPosition);
                // アラート表示
                AlertDialog.Builder dlg = new AlertDialog.Builder(MainActivity.this);
                dlg.setTitle("クリック!")
                .setMessage(item.get(KEY1))
                .setPositiveButton("OK", null)
                .show();

                return false;
            }
        });

        // グループの親項目がクリックされた時の処理
        lv.setOnGroupClickListener(new OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View view,
                    int groupPosition, long id) {
                ExpandableListAdapter adapter = parent.getExpandableListAdapter();
                // クリックされた場所の内容情報を取得
                @SuppressWarnings("unchecked")
                Map<String, String> item = (Map<String, String>)adapter.getGroup(groupPosition);
                // アラート表示
                AlertDialog.Builder dlg = new AlertDialog.Builder(MainActivity.this);
                dlg.setTitle("クリック!")
                .setMessage(item.get(KEY1))
                .setPositiveButton("OK", null)
                .show();

                return false;
            }
        });
    }

}

以上です。

40
41
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
41