ListViewについて色々とやってきましたが、今回で最後にします。
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の良いところですね~
次回はアプリには大抵用意されている「設定画面」を作ってみたいと思います。