ListViewはリストを画面に表示するクラスでしたが、
リストを選択すると更にリストが表示される、
階層表示を実装してみます。
まずはJavaのコードです。
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.ExpandableListAdapter; import android.widget.ExpandableListView; import android.widget.SimpleExpandableListAdapter; import android.widget.Toast; public class ListView11 extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // ExpandableListViewインスタンスを取得 ExpandableListView listView = (ExpandableListView) findViewById(R.id.list); // 親のリストを格納するArrayListインスタンスを生成 List<Map<String, Object>> parentsList = new ArrayList<Map<String, Object>>(); // parentsListにデータを追加 parentsList.add(getParentData("親1")); parentsList.add(getParentData("親2")); // 子のリストを格納するArrayListインスタンスを生成 List<List<Map<String, Object>>> childrenList = new ArrayList<List<Map<String, Object>>>(); // 子リストにデータを追加 childrenList.add(getChildList("子1-1", "子1-2")); // 親1に対応 childrenList.add(getChildList("子2-1", "子2-2")); // 親2に対応 // SimpleExpandableListAdapterインスタンスを生成 SimpleExpandableListAdapter adapter = new SimpleExpandableListAdapter( this, parentsList, android.R.layout.simple_expandable_list_item_1, new String[]{"parent_text"}, new int[]{android.R.id.text1}, childrenList, R.layout.row, new String[]{"child_text"}, new int[]{R.id.child_text} ); // 作成したアダプタをExpandableListViewにセットする listView.setAdapter(adapter); // クリック時のリスナを設定 listView.setOnChildClickListener( new ExpandableListView.OnChildClickListener() { @SuppressWarnings("unchecked") // ジェネリクスを使用したキャストの為 @Override public boolean onChildClick( ExpandableListView parent, View view, int groupPosition, int childPosition, long id) { // アダプタからデータを取得してトーストで表示 ExpandableListAdapter adapter = parent. getExpandableListAdapter(); Map<String, Object> childMap = (Map<String, Object>)adapter. getChild(groupPosition, childPosition); Toast.makeText( ListView11.this, childMap.get("child_text").toString(), Toast.LENGTH_SHORT ).show(); return false; } }); } /** * 親リストに格納するデータを返す * * @param object 親リストに格納するMapのvalue値 * @return parentData 親リストに格納するMap */ private Map<String, Object> getParentData(Object object) { Map<String, Object> parentData = new HashMap<String, Object>(); parentData.put("parent_text", object); return parentData; } /** * 子リストに格納するデータを返す * * @param object 子リストに格納するMapのvalue値の配列 * @return childList 子リストに格納するList */ private List<Map<String, Object>> getChildList(Object... object) { List<Map<String, Object>> childList = new ArrayList<Map<String, Object>>(); // 引数に渡されたオブジェクトの数だけ子リストを追加 for (Object o : object) { Map<String, Object> childData = new HashMap<String, Object>(); childData.put("child_text", o); childList.add(childData); } return childList; } }長ったるいコードですが、やっている事は単純です。
1. ExpandableListViewクラスのインスタンスを生成(22行目)
⇒これが画面に表示されるリストの骨格です。
名前の通りListViewを継承しています。
2. SimpleExpandableListAdapterクラスのインスタンスを生成(42行目)
⇒ExpandableListViewに値をセットする為のアダプタ。
親リストと子リストをコンストラクタで渡してやる事で、
階層表示を可能にします。
3. ExpandableListViewにSimpleExpandableListAdapterをセット(55行目)
⇒作成したアダプタをリストビューに設定する事で、
親リストと子リストが格納されます。
その他にクリックリスナーを設定していたり、
privateなメソッドで親リストや子リストの生成を行っていますが、
今回の主題であるリストの階層表示には直接関係ありません。。。
続いて"res/layout/main.xml"のコードです。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/parent" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ExpandableListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>ここで設定しているExpandableListViewが親リストとなります。
"res/layout/row.xml"のコードです。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/child_text" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>TextViewが子リストの要素となります。
上記のコードを実行すると、次のように表示されます。
親リストをタップする事で子リストが表示されます。
今回は親リストに対して、子リストを2件ずつ設定しましたが、
子リストにあたるArrayListの要素数だけ表示する事が可能です。
ListViewを4回程学習してきましたが、
各パターンごとに専用のアダプタが用意されており、
使い方さえわかれば初心者のsirocoでも実装は難しくないと感じました。
色々なAPIが用意されているのもAndroidの良いところですね~
次回はアプリには大抵用意されている「設定画面」を作ってみたいと思います。
0 件のコメント:
コメントを投稿