ListView の基本的な使い方
何らかのデータのリストを表示したい場合は、良くあることですよね。
例えばコンタクトリストのデータを引いてきて、それの一覧表示をするとか、あるいは最近通話したヒストリを一覧表示するとか・・・あるいは、 そうしたシステムが持っているデータではなく、自前のアプリケーションのデータを一覧表示するなど。
ここではそんな状況で便利に使えるウィジェットについて基本的な使用方法を説明します。
スワイプ動作とリストのリフレッシュを組み合わせる方法については「SwipeRefreshLayout の使い方と非同期処理」もみてください。
ListView と ListActivity
一般的なデータリストを表示するために、 ListView というウィジェットが用意されています。 ListView はデータを縦方向に並べて表示して、必要に応じてスクロールします。
例えば次のスクリーンショットを見てください。
ここでは "Hello!" という文字列が複数個、 ListView に表示されています。数が多くなれば自動的に上下にスクロール可能となり、すべてのデータをみることができます。
ちなみに ListView を組み込んだ (ホストする) アクティビティとして ListActivity というのもありますが、 ListView さえ理解しておけば、ListActivity も使えるのでここではベースとなる ListView にフォーカスしたいとおもいます。
ListView を利用した簡単なプログラム
では実際に ListView を使ってみましょう。
ここで作るものは次のようなプログラムです。最初はデータは含まれていません。
下に配置したボタンを一回押すたびに、リストに "Hello!" という文字が追加されます。
最初はプログラム全体のレイアウトです。 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_height="wrap_content"
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_weight="1"></ListView>
<Button
android:text="Button"
android:id="@+id/button1"
android:layout_height="wrap_content"
android:layout_width="match_parent"></Button>
</LinearLayout>
リニアレイアウトで、上下に ListView と Button を配置しています。
次にボタンをクリックして addItem というメソッドを呼び出すところまで書いてみましょう。 これは特に ListView っぽい点は何もありません。クリックリスナーを設定しているだけ ですから、これが分からない人はクリックリスナーの設定方法のページをみてください。
package com.keicode.android.test;
...
public class ListViewTest1 extends Activity
implements OnClickListener {
static final String TAG = "ListViewTest";
ListView listView;
Button addButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViews();
setListeners();
}
protected void findViews(){
listView = (ListView)findViewById(R.id.listView1);
addButton = (Button)findViewById(R.id.button1);
}
protected void setListeners(){
addButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.button1:
addItem();
break;
}
}
protected void addItem(){
...
}
}
アダプターの設定
それでは次に ListView とデータを結びつけます。
ここでは文字列データは ArrayList<String> として保持します。
ListView とリストを結びつけるのは、 アダプター (Adapter) です。アダプターは android.widget.BaseAdapter から派生したオブジェクトです。
特に配列やリストと結びついて使うために、 ArrayAdapter (android.widget.ArrayAdapter<T>) があります。ここでは ArrayAdapter を使って、 ListView にコレクションを結びつけます。
package com.keicode.android.test;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
public class ListViewTest1 extends Activity
implements OnClickListener {
static final String TAG = "ListViewTest";
...
static List<String> dataList = new ArrayList<String>();
static ArrayAdapter<String> adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
...
setAdapters();
}
...
protected void setAdapters(){
adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
dataList);
listView.setAdapter(adapter);
}
protected void addItem(){
adapter.add("Hello!");
}
}
上のコードでは setAdapters というメソッド内でアダプターオブジェクトを生成しています。キモとなる部分なので、 少し詳しく見てみましょう。ここです。
adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
dataList);
listView.setAdapter(adapter);
ArrayAdapter のコンストラクタの第二引数にみえる android.R.layout.simple_list_item_1 というものは何でしょうか。
これはアンドロイドのシステム (フレームワーク内) で定義されているレイアウト定義です。具体的には simple_list_item_1 では TextView がひとつだけ定義されています。 このレイアウトに従ってリスト形式のビューを表示しなさい、ということですから、ここでは TextView のリストを表示する、ということになります。
第三引数に ArrayList<String> のインスタンスである、 dataList がセットされています。
アダプターを生成したら、 ListView の setAdapter メソッドでリストビューにアダプターをセットします。
これで、アダプターを介してリスト (コレクション) のインスタンスと、 ListView が繋がりました。
コレクションの更新
コレクションを変更する時はアダプターを介して行います。こうすることで、アダプターはデータに変更があったことが直ちに分かるので、ビューの更新も行うことができます。
逆にもし、コレクションを直接操作してしまうと、アダプターはコレクションに変更があったことが分からないので、ビューの更新をするタイミングがわかりません。 このため通常は ArrayAdapter を使うならアダプターの add メソッドを利用してコレクションを操作すると良いでしょう。
コレクションを直接操作した場合は、アダプターの notifyDataSetChanged メソッドを呼ぶことで、 アダプターに関連づいているデータセットに変更したことをアダプターに知らせることもできます。
大量のデータ操作を行う場合などは、直接コレクションに対してデータ操作を行い、 最後にアダプターの notifyDataSetChanged を呼びだしてビューを更新した方が効率よいでしょう。