ListViewとListActivity(3)-応用編
今回は、ListViewとAdapterクラスを組み合わせた、いろいろなパターンについてみていきます。
プログラムはListViewウィジェットを使って書かれていますが、これらはすべて、ListActivityを使って実現する事もできます。
BaseAdapterクラスを拡張してリスト項目のレイアウトを自由にカスタマイズする。
BaseAdapterは、ArrayAdapterクラスのスーパクラスです。
BaseAdapterを継承したクラスには、ArrayAdapterの他にもCursorAdapter, SimpleAdapter等があります。
BaseAdapterクラスは、他のAdapterクラスの基となるクラスです。
このBaseAdapterクラスを拡張して、独自のAdapterクラスを定義して、getViewメソッドをオーバライトすることで、 リスト項目のレイアウトを自由にカスタマイズする事ができます。
以下にその例を示します。
リスト10(ListViewSample6.java)
ListViewSample6クラスの内部クラスPerson(18行目)は、名前と年齢データを保持するクラスです。
BaseAdapterクラスを拡張して、Personクラス専用のAdapterクラスとなるListPersonAdapterクラス(36行目)を定義しています。
ListPersonAdapterクラスでは、getViewメソッドをオ-バーライトしています。
getViewメソッドの戻り値となるViewオブジェクトは、リスト項目を表示するViewオブジェクトとなります。
従って、このViewオブジェクトに独自のレイアウトを持つViewオブジェクトを指定すれば、独自のレイアウトを持つリスト項目の表示が可能になります。
このgetViewメソッドでは、TextViewオブジェクトを2つ作成して、 変数positionが示す列位置にある、Personオブジェクトのnameフィールドとageフィールドの値を表示するように指定しています。
このプログラムを実行すると、以下のような画面が表示されます。
このプログラムには、実は欠点があります。
リスト項目を1列表示するたびに、毎回新しいウィジェットを作成しているので、リソースの無駄使いをしている事です。
このプログラムを、以下のように修正する事で、リスト項目のウィジェットを使い回す事ができるようになります。
リスト11(ListViewSample7.java)
修正したgetViewメソッド内の処理をみていきます。
getViewメソッドの第2引数convertViewには、前回使用したViewオブジェクトが渡されます。
もし、このオブジェクトがnullの場合、まだViewオブジェクトは作成されていません。
このため、convertViewがnullの場合は新しいViewオブジェクトを作成します。
そして、このViewオブジェクト内に配置される子ウィジェットを作成し、 その子ウィジェットの参照を格納するために、 独自に定義(36行目)したクラスViewHolderを作成して子ウィジェットの参照を格納します。
このViewHolderオブジェクトを、convertViewのTagに格納します。
Tagは、Viewオブジェクトで自由に使えるデータを保存するポケットのようなもののようです。
convertViewがnullでない場合には、既にViewオブジェクトは作成済みですので、 このViewオブジェクトすなわちconvertViewより、子ウィジェットの参照を保持しているViewHolderをTagより取得します。
新たに、オブジェクトを作成する必要はありません。
その後は、各子ウィジェットに対しての処理をおこないます。
getViewメソッドでレイアウトファイルを使う
getViewメソッドで作成するViewに、レイアウトファイルを使う事もできます。
以下にその例を示します。
リスト12(1)-レイアウトファイル(list_row.xml)
リスト12(2)-Javaソースの修正部分のみ(ListViewSample7.java)
リスト11内のgetViewメソッドを、リスト12(2)のように修正します。
76,77行目でインフレータを使って、Viewオブジェクトを取得しています。
選択不可のリスト項目を指定する。 - BaseAdapterのisEnabledメソッド
BaseAdapterクラスのisEnabledメソッドをオーバライトすると、選択不可のリスト項目を指定する事ができます。
リスト11において、ListPersonAdapterクラスにisEnabledメソッドをオーバライトして、 以下のコードをを挿入すると、2番目のリスト項目(position = 1)が選択できなくなります。
リスト13(ListViewSample7.java)
ArrayAdapterクラスを拡張する。
ArrayAdapterクラスもBaseAdapterを継承しているので、getViewメソッドを使ってレイアウトを自由にカスタマイズする事ができます。
ここでは、「謎めいたインテント」の「アクションを使って他のアプリケーションのコンポーネントを呼び出す。」の項で紹介した、 「インテントプログラム1」と 同じような機能を、 ListViewとArrayAdapterクラスを拡張したクラスを使って実現してみます。
リスト14(1)-レイアウトファイル(list_row.xml)
リスト14(2)-Javaソース(ListViewSample8.java)
このプログラムを実行すると、以下の図のようにリスト表示項目に、TextViewウィジェットとButtonウィジェットが表示されます。
各リスト項目のボタンをクリックすると、「インテントプログラム1」を実行した時と同じように、 Webブラウザや地図表示等のあらかじめアンドロイドに用意されているアプリケーションが呼び出されます。
リスト14(2)のコードをみていきます。
31行目のIntentItemArrayAdapterクラスは、ArrayAdapterクラスを拡張したクラスです。
IntentItemArrayAdapterクラスは、IntentItemオブジェクト(18行目で定義)のリストを内部に持ちます
IntentItemオブジェクトは、ListViewのリスト項目の情報を保持しています。
IntentItemクラスのtitleフィールドとbuttonTextフィールドは、それぞれリスト14(1)のレイアウトファイルに記述されている、 TextViewウィジェットとButtonウィジェットに表示される文字列が格納されます。
intentフィールドには、ボタンが押された時に実行されるインテントが格納されます。
インテントについては、「謎めいたインテント」を参照して下さい。
IntentItemArrayAdapterクラスでは、getViewメソッドをオーバライトして、リスト項目を表示するためのViewオブジェクトを操作しています。
convertView引数がNullの場合は、レイアウトファイルよりViewオブジェクトを取得しています(45行目)。
47行目~57行目で、TextViewウィジェットとButtonウィジェットの表示文字列と、Buttonのイベントリスナーを設定しています。
69行目~76行目で、リスト項目であるIntentItemオブジェクトを作成して、これをAdapterオブジェクトに追加しています。
SimpleAdapterクラス-もっと簡単にレイアウトをカスタマイズ
SimpleAdapterクラスを使うと、 Adapterクラスを拡張したクラスを定義してgetViewメソッドをオーバライトしなくても、 Mapクラスを使って、もっと簡単にリスト項目のレイアウトをカスタマイズする事ができます。
前項と同じく、Webブラウザや地図表示等のインテントの実行を、 今度はボタンではなくリスト項目がクリックされた時におこなうプログラムを、SimpleAdapterクラスを使って実装してみます。
リスト15(1)-レイアウトファイル(list_row.xml)
リスト15(2)-Javaソース(ListViewSample9.java)
このプログラムを実行すると、以下の画面が表示されます。
リスト項目をクリックすると、インテントが実行されます。
Mapのキーに指定した値が、レイアウトファイルのウィジェットのIDと一致していると、Mapの値がウィジェットに表示されるのがわかります。
SimpleCursorAdapterクラス-コンテンツプロパイダーよりデータを取得してリスト表示する。
SimpleCursorAdapterクラスを使うと、コンテンツプロパイダーよりデータを取得して、「連絡先」などの情報を簡単に、リスト表示させる事ができます。
以下に、そのプログラムの例を示します。
リスト16(1)-Javaソース(ListViewSample10.java)
21行目の「android.R.layout.simple_list_item_2」は、アンドロイドにあらかじめ定義されているレイアウトのIDです。
コンテンツプロパイダーよりデータを取得するためには、マニュフェストファイルの修正も必要です。
リスト16(2)-マニュフェストファイル(AndroidManifest.xml)
ArrayAdapterクラスとリソース
配列データをリソースファイルに定義して、そのリソースファイルからArrayAdapterオブジェクトを生成する事がでます。
以下は、そのサンプルを示します。
リスト17(1)-配列データのリソースファイル(res/values/arrays.xml)
リスト17(2)-Javaソース(ListViewSample11.java)
更に、レイアウトファイルのListViewウィジェットの属性に配列データのリソースファイルを指定する事ができます。
リスト15(1)-レイアウトファイル(list_row.xml)
リスト15(2)-Javaソース(ListViewSample12.java)
プロジェクト作成時のJavaソースから、いっさい手を加えずにListViewの表示ができました。
参考URL
「ListViewとListActivity」に関連する参考URLを以下に示します。- Android Developers