:Tips  ListView を使おう 〜 基礎編 〜 その1

 ListView と銘打ちながら、余りにも ListView とかけ離れた内容になってしまったので、前2回の表題を ListView から JSON に変更せざる得ない事態に陥りました・・・。 しかし、ここからは本題に戻り、正真正銘 ListView をテーマに書いていきたいと思います。



ListView 作成時に必ず必要となるもの

ListView を用いる上で必ず必要となるものが幾つかあります。1つ目は当然ですが「 ListView 」。2つ目は「 Adapter 」。3つ目は「 データ 」。そして、(一部例外もありますが)4つ目に「 レイアウト情報 」です。



ListView 作成の大まかな手順・・・



  データ   ─┐
         ├─→ Adapter ─→ ListView
レイアウト情報 ─┘
上の図の矢印は作業手順の「流れ」を示しています。「参照関係」は矢印が逆向きになります。




1.「 データ 」 を作成。

2.「 レイアウト情報 」 を作成。

3.「 Adapter 」 を作成し、 「 データ 」「 レイアウト情報 」 をセット。

4.「 ListView 」 を作成し、 「 Adapter 」 をセット。



ListView の形態・作成手法は様々ですが、大まかな手順に違いがあるわけではありません。上記のステップを1つ1つクリアしていくことで ListView は完成します。



データ

データとは、 ListView を使って 「 一覧表示したい情報 」 の集まりの事です。主に、文字列や画像などが対象になります。形態としては Object の「配列」か、または java.util.List インターフェイス実装クラスか、 android.database.Cursor インターフェイス実装クラスの何れかの形で用意することになります。



レイアウト情報

レイアウト情報とは、 ListView を使ってデータの"要素"を表示させる際に用いる 「 View のレイアウト 」 の事です。 リソースのレイアウトフォルダ( /res/layout )配下に XML ファイルとして用意します。 ListView では、自動で表示用 View の生成や管理(使い回し)を行うという性格上、 ”設計図” であるレイアウト情報のみを要求します(たとえ、使用する View が TextView 1つだったとしても、同様にレイアウト情報の XML ファイルが必要となります)



Adapter

Adapter とは、 ListView からの指示を受けて 「 表示用の View にデータをセットする 」 という役割を担っています。具体的には android.widget.ListAdapter インターフェイス実装クラスがこれに当たります。この ListAdapter の実装こそが ListView の開発での"肝"になります。



主な ListAdapter 実装クラス・・・

ArrayAdapter

「 配列 」 または 「 List 」 のデータ要素(文字列)を、レイアウト情報(内)の TextView (または TextView 継承クラス)にセットする Adapter です。機能的に最もシンプルな Adapter といえるでしょう。



 java.lang.Object
  ↳ android.widget.BaseAdapter
   ↳ android.widget.ArrayAdapter


public ArrayAdapter(Context context, int textViewResourceId) 
public ArrayAdapter(Context context, int resource, int textViewResourceId) 
public ArrayAdapter(Context context, int textViewResourceId, T[] objects) 
public ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects) 
public ArrayAdapter(Context context, int textViewResourceId, List<T> objects) 
public ArrayAdapter(Context context, int resource, int textViewResourceId, List<T> objects) 

コンストラクタは全部で6つあります。 context には通常 Activity の インスタンス を渡します。 resource には レイアウト情報自身のID ( R.layout.* ) を、 textViewResourceId にはレイアウト情報で定義( android:id="@+id/*" )された個別の TextView の参照用ID ( R.id.* ) を渡します。ここで注意すべきポイントは、1番目と5番目のコンストラクタのように引数に resource が無く、 textViewResourceId のみが引数として示されている場合です。この場合、 textViewResourceId に渡さなければならない引数はレイアウト情報自身のIDであって TextView の参照用IDではないという点を理解しておくことが重要です(この場合の textViewResourceId という命名は明らかに誤った使い方です。 resource という命名を使えないのならば、せめて textViewResource とでもすべきです)。残りの objects にはデータの参照を渡します。

SimpleAdapter

「 List 」 のデータ要素 ( java.util.Map 実装クラス ) を、レイアウト情報内の ”複数” の View にセットする Adapter です。 ArrayAdapter と比べると使い方は少々面倒ですがレイアウトに柔軟性があります。最も利用頻度の高い Adapter でしょう。



 java.lang.Object
  ↳ android.widget.BaseAdapter
   ↳ android.widget.SimpleAdapter


public SimpleAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) 

コンストラクタは1つです。1つ目の引数 context には通常 Activity の インスタンス を渡します。2つ目の引数 data にはデータの参照を渡します(このデータの参照は List インターフェイス実装クラスの参照です。そして、この List の要素には Map インターフェイス実装クラスの参照が入っている必要があります)。3つ目の引数 resource には レイアウト情報のID ( R.layout.* ) が渡されます。4つ目の引数 from には2つ目の引数で渡された List の要素 Map の「 キー 」になっている文字列配列として渡します。 Adapter 側は、この「 キー 」を用いて2つ目の引数で渡された Map から「 値 」を取り出す処理をします。最後の5つ目の引数 to にはレイアウト情報で定義( android:id )された個別の View の参照用ID ( R.id.* ) の配列を渡します。 Adapter 側は Map から取り出した「 値 」を5つ目の引数で渡された参照用IDの View にセットします。(具体的には from[0] の文字列を「キー」として Map から取り出した「値」を to[0] の View にセットします。続けて、 from[1]→to[1] from[2]→to[2] ..... from[n-1]→to[n-1] と順に処理されていきます)



ListView

ListView とは、リスト形式で 「 複数のアイテム( View )を縦方向に並べて表示 」 するためのウィジェットGUIコンポーネント)クラスです。 他のレイアウトクラス(例えば LinerLayout )との大きな違いは、リスト表示の1単位である View に表示される情報(テキストデータ)を自動でセットしたり、また(メモリの使用量を極力抑えるため) 表示の際に使用する各 View の生成、保存、再利用、破棄に関しても ListView が管理を行う、という点が異なります(正確には View の"生成"と情報の"セット"は ListView に組み込まれた ListAdapter インターフェイス実装クラスで行われます)



ListView の継承関係・・・

 java.lang.Object
  ↳ android.view.View
   ↳ android.view.ViewGroup
    ↳ android.widget.AdapterView
     ↳ android.widget.AbsListView
      ↳ android.widget.ListView


public ListView (Context context) 

コンストラクタは3つありますが、他の2つは割愛させていただきます。context には Context のインスタンスを渡しますが、通常は Activity の参照が渡されます。



リソースの XML ファイルのみで ListView を作成する

ちょっと特殊なケースの ListView 作成方法です。作成手順が不明瞭になるので書くのは避けようかとも考えましたが、作成方法自体は簡単なので冒頭で手短に説明します。

< STEP 1 > データを作成する

/res/values フォルダに新たに XML ファイルを作成します。ファイル名は自由ですが、ここでは arrays.xml とします。そして、 <resources> タグの間に <arry> または、 <string-array> タグを作り属性 name に任意の文字列を設定します。ここでは、 listview-items としました。次に、 <arry> タグの間に <item> タグを設け要素に ListView に表示したい文字列を設定します。

res/values/arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<array name="listview_items">
		<item>Message 1</item>
		<item>Message 2</item>
		<item>Message 3</item>
		<item>Message 4</item>
		<item>Message 5</item>
	</array>
</resources>

このケースでは、配列 や List には変換はしません。



< STEP 2 > レイアウト情報を作成する

ListView のレイアウト情報だけを作成します。今回は /res/layout/main.xml を利用します。

res/layout/main.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="fill_parent"
    >
    <ListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:entries="@array/listview_items"
        />
</LinearLayout>

重要な点は <ListView> タグの属性 android:entries の値に、先程作成した XML ファイルのIDを設定することです。



< STEP 3 > Adapter を作成する

今回、この作業はありません。



< STEP 4 > ListView を作成する

今回は、 Activity 内で setContentView() メソッドの引数に /res/layout/main.xml のIDを渡すだけです。

public class ListViewTest extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
    }
}

以上です。実行してみます。




このケースの場合、実際には ListView のコンストラクタ内で ArrayAdapter インスタンスが作成され、自身にセットするという処理がなされいます。表示に利用される TextView のレイアウト情報は com.android.internal.R.layout.simple_list_item_1 という、Android が持っているレイアウト情報を利用しているようです。





次回は・・・

ArrayAdapter を利用した ListView の作成方法を具体的に見ていきます。