ListAdapterについて調べてみた(1) ArrayAdapter編
ArrayAdapterを継承して,getViewをオーバーライドしたり,Adapter内でViewHolderをインナークラスで定義したり,セルのビューのタグにホルダーをセットしたりなどは今回しません。ArrayAdapterを継承せずに,そして非常に少ないコード記述量で使ってみます。
ArrayAdapterクラスのコンストラクタは,TextView単体のレイアウトXMLファイルのidを引数にとったり,レイアウトXMLファイルのidとその中のTextViewのidを引数に取ったりするものがあります。リスト内のセルの構成要素がTextViewだけ,もしくは単一のTextViewの表示内容だけがセルごとに異なる場合,非常に少ないコード記述量でリストを表示できるようです。(もちろんArrayAdapterは,getViewメソッドをオーバーライドすることで,画像や複数のTextViewが一つのセル内にあるようなリストを作ることも可能です。)
シンプルな使い方
(多分一度は見たことがある)ArrayAdapterの基本的な使い方。
下記のようなTextViewのみで構成されているレイアウトXMLファイルを用意します。
res/layout/list_item_text_view.xml
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/label" android:layout_width="match_parent" android:layout_height="40dp" android:gravity="center" android:text="Label" > </TextView>
このレイアウトXMLファイルのidと,文字列の配列からArrayAdapterのインスタンスを作ります。(ActivityのonCreate内。thisはActivityのインスタンス)
String[] strings = new String[] { "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日" }; int itemLayoutId = R.layout.list_item_text_view; ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, itemLayoutId, strings);
このAdapterを用いてテキストのみの簡単なリストを表示することが可能です。
また,配列でなくリストを用いるコンストラクタも用意されています。
ちなみに,試しにやってみたいけれどTextViewのみで構成されたレイアウトXMLファイルを作るのが面倒な場合,android.R.layout.textを使うといいと思います。
オブジェクトの文字情報をリストに表示
次のようなクラスを定義し,このクラスの文字情報をリスト内のセルに表示しします。
public class Person { private final String name; private final int age; Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return String.format("名前:%s 年齢:%02d歳", name, age); } }
アダプターの作成は以下の通りです。
(ActivityのonCreate内。thisはActivityのインスタンス)
Person[] persons = new Person[] { new Person("太郎", 25), new Person("次郎", 22), new Person("三郎", 19), new Person("四郎", 16), new Person("五郎", 13), }; int itemLayoutId = R.layout.list_item_text_view; ArrayAdapter<Person> adapter = new ArrayAdapter<Person>(this, itemLayoutId, persons);
これをListViewにセットすると先頭のセルには下記のように表示されます。
名前:太郎 年齢:25歳
二番目以降のセルも,それぞれのPerson型のインスタンスのtoStringの結果がセルに表示されています。
実は「オブジェクトの文字情報をリストに表示」のコンストラクタと,最初に紹介した「シンプルな使い方」のコンストラクタは同一のものです。
使っているコンストラクタの定義は,
ArrayAdapter(Context context, int resource, T[] objects)
となっています。
前者はString型を,後者はPerson型の配列をコンストラクタの引数として渡しています。
String[]型の場合も他の型の配列の場合も,セルの表示の際に表示するデータ要素のオジェクトのtoStringメソッドを呼び出しています。
そのため,任意の型の文字情報を表示したい場合,ToStringメソッドを実装すればその情報をセルに表示することが可能です。
リソースで定義した文字列配列を表示する
リソースファイル内に定義した下記のような文字列配列
res/values/arrays.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="day_array"> <item>日曜日</item> <item>月曜日</item> <item>火曜日</item> <item>水曜日</item> <item>木曜日</item> <item>金曜日</item> <item>土曜日</item> </string-array> </resources>
これをリストで表示するためのAdapterを作成します。
(ActivityのonCreate内。thisはActivityのインスタンス)
int itemLayoutId = R.layout.list_item_text_view; int textArrayResId = R.array.day_array; ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, textArrayResId, itemLayoutId);
ArrayAdapterのクラスメソッドを用いてインスタンスを生成出来ました。
上記は3行ですが,実質1行で書けますね。
カスタマイズしたセル中にテキスト情報を表示する
下記のようなレイアウトXMLファイルを定義します。
res/layout/list_item_text_in_layout.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="40dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toLeftOf="@+id/label" android:text="曜日:" /> <TextView android:id="@+id/label" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Label" > </TextView> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:src="@drawable/ic_launcher" /> </RelativeLayout>
このレイアウトXMLファイルと,
ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
というコンストラクタを使います。(ActivityのonCreate内。thisはActivityのインスタンス)
String[] strings = new String[] { "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日" }; int itemLayoutId = R.layout.list_item_text_in_layout; int textViewId = R.id.label; ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, itemLayoutId, textViewId, strings);
ここで使っているコンストラクタは,第2引数にセルのレイアウトXMLファイルのidを,第3要素にセル内のTextViewのidを取ります。コンストラクタの第3引数で渡した配列の各要素の文字列は,第2要素で渡したidが示すTextView(ここではlabelというidのTextView)に表示されます。
これを使えば,セルに背景を設定したり,画像を複数個表示したり,他のTextViewを持つセルの表示も容易です。
まとめ
ArrayAdapter(もしくはBaseAdapter)のgetViewメソッドをオーバーライドしたり,内部にViewHolderを定義したり,セルのビューのタグにViewHolderをセットしたりして,リストを表示するのは,(定型パターンではありますが)やはり多少面倒です。
試しにささっとデータをリストで表示してみたい場合や,文字列のみが変わるリストを表示したい場合,ArrayAdapterを適切に使い少ないコード量でリストを作成すりことも可能です。
ただし,TextViewではなくImageViewの要素をセルごとに設定したい,セルごとに複数のTextViewの値を設定したい,画像と文字列両方セルごとに設定したい場合は,
getViewメソッドをオーバーライドするか,SimpleAdapterを使う必要があります。
参考:
http://developer.android.com/reference/android/widget/ArrayAdapter.html