[Android] データの取り扱い - ArrayAdapter ================================================================================ データベースから取得したデータを、ListView を使って表示する。 このとき、ArrayAdapter クラスをカスタマイズすることで、オブジェクトの配列やリス ト (List) から、自動的に値を ListView に展開してリスト表示することができる。 基本的な設定・手順は以下のとおり。 ・表示したいレイアウト(main.xml)で、ListView を設定 ・1 行分のレイアウト(row.xml)を設定 ・オブジェクトを設定するためのクラス(ArrayAdapter を継承)を作成 ・コンストラクターで、オブジェクト配列(リスト)を指定 ・getView() メソッドをオーバーライドして、1 行分の項目を紐付け ・ListView.setAdapter() メソッドで、アダプターを ListView に設定 ▲ アクティビティ 変更点は、以下の 2 箇所のみ。 ・ArrayAdapter のサブクラス(ItemListAdapter)のコンストラクターで、row.xml とオブ ジェクトのリストを紐付け ItemListAdapter<Item> adapter = new ItemListAdapter<Item>(this, R.layout.row, itemList); // (1) ・ListView.setAdapter() メソッドで、アダプターを ListView に設定 ListView listView = (ListView) findViewById(R.id.listView1); listView.setAdapter(adapter); // (2) □ Database02Activity.java --- package jp.marunomaruno.android.database; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.ListView; import android.widget.Toast; public class Database02Activity extends Activity { private EditText name = null; private EditText comment = null; private DatabaseHelper dbHelper = null; private int TOAST_DURATION = Toast.LENGTH_SHORT; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); name = (EditText) findViewById(R.id.name); comment = (EditText) findViewById(R.id.comment); dbHelper = new DatabaseHelper(this); } @Override public void onPause() { super.onPause(); if (dbHelper != null) { // dbHelper.close(); } } public void onFindButtonClick(View view) { List<Item> itemList = dbHelper.select(name.getText()); if (itemList.size() <= 0) { Toast.makeText(this, getString(R.string.notFoundMessage), TOAST_DURATION).show(); return; } name.setText(itemList.get(0).getName()); comment.setText(itemList.get(0).getComment()); ItemListAdapter adapter = new ItemListAdapter(this, itemList); // (1) ListView listView = (ListView) findViewById(R.id.listView1); listView.setAdapter(adapter); // (2) Toast.makeText( this, String.format(getString(R.string.findMultipleMessage), itemList .size()), TOAST_DURATION).show(); } public void onSaveButtonClick(View view) { long id = dbHelper.insert(name.getText(), comment.getText()); name.setText(""); comment.setText(""); if (id > 0) { Toast.makeText(this, String.format(getString(R.string.saveMessage), id), TOAST_DURATION).show(); } else { Toast.makeText(this, getString(R.string.notSaveMessage), TOAST_DURATION).show(); } } public void onUpdateButtonClick(View view) { int count = dbHelper.update(name.getText(), comment.getText()); if (count > 0) { Toast.makeText(this, String.format(getString(R.string.updateMessage), count), TOAST_DURATION).show(); } else { Toast.makeText(this, getString(R.string.notUpdateMessage), TOAST_DURATION).show(); } } public void onRemoveButtonClick(View view) { int count = dbHelper.delete(name.getText()); name.setText(""); comment.setText(""); if (count > 0) { Toast.makeText(this, String.format(getString(R.string.removeMessage), count), TOAST_DURATION).show(); } else { Toast.makeText(this, getString(R.string.notRemoveMessage), TOAST_DURATION).show(); } } } --- (1) ArrayAdapter のサブクラス(ItemListAdapter)のコンストラクターで、オブジェクト のリストを設定 ItemListAdapter adapter = new ItemListAdapter(this, itemList); // (1) (2) ListView.setAdapter() メソッドで、アダプターを ListView に設定 ListView listView = (ListView) findViewById(R.id.listView1); listView.setAdapter(adapter); // (2) ・ListView クラスのアダプターの設定メソッド --- void setAdapter(ListAdapter adapter) --- ▲ アダプター ListView の各行に、リストや配列の要素を割り当てるためのアダプター。 項目が複数あるような場合は、ArrayAdapter クラスを継承して、カスタマイズしたアダ プター・クラスを作って対応する。 手順としては、getView() メソッドをオーバーライドして、そこに、各項目のデータを割 り当てることになる。 □ ItemListAdapter --- package jp.marunomaruno.android.database; import java.util.List; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TextView; public class ItemListAdapter extends ArrayAdapter<Item> { // (1) public ItemListAdapter(Context context, List<Item> objects) { // (2) super(context, 0, objects); // (3) } public ItemListAdapter(Context context, Item[] objects) { // (4) super(context, 0, objects); } public ItemListAdapter(Context context, int resource, int textViewResourceId, List<Item> objects) { super(context, resource, textViewResourceId, objects); } public ItemListAdapter(Context context, int resource, int textViewResourceId, Item[] objects) { super(context, resource, textViewResourceId, objects); } public ItemListAdapter(Context context, int resource, int textViewResourceId) { super(context, resource, textViewResourceId); } public ItemListAdapter(Context context, int textViewResourceId, List<Item> objects) { super(context, textViewResourceId, objects); } public ItemListAdapter(Context context, int textViewResourceId, Item[] objects) { super(context, textViewResourceId, objects); } public ItemListAdapter(Context context, int textViewResourceId) { super(context, textViewResourceId); } @Override public View getView(int position, View convertView, ViewGroup parent) { // (5) if (convertView == null) { LayoutInflater layoutInflater = (LayoutInflater) getContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); // (6) convertView = layoutInflater.inflate(R.layout.row, null); // (7) } Item item = getItem(position); // (8) TextView id = (TextView) convertView.findViewById(R.id.idInList); // (9) id.setText(String.valueOf(item.getId())); // (10) TextView name = (TextView) convertView.findViewById(R.id.nameInList); name.setText(item.getName()); TextView comment = (TextView) convertView .findViewById(R.id.commentInList); comment.setText(item.getComment()); return convertView; // (11) } } --- public class ItemListAdapter extends ArrayAdapter<Item> { // (1) ArrayAdapter クラスを継承して作る。 ArrayAdapter クラスは、総称型となっているので、今回は、Item 型に限定して作る。 ・ArrayAdapter クラス オブジェクトの配列やリストと、行のレイアウトの項目を紐付けるためのアダプター・ク ラス。 java.lang.Object - android.widget.BaseAdapter - android.widget.ArrayAdapter<T> ・主なコンストラクター --- ArrayAdapter(Context context, int textViewResourceId, T[] objects) ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects) ArrayAdapter(Context context, int textViewResourceId, List<T> objects) ArrayAdapter(Context context, int resource, int textViewResourceId, List<T> obje cts) --- ・主なメソッド --- void add(T object) void addAll(Collection<? extends T> collection) void addAll(T... items) void clear() int getCount() T getItem(int position) long getItemId(int position) int getPosition(T item) void insert(T object, int index) void remove(T object) --- (2)(3)(4) 独自コンストラクターの定義 ArrayAdapter クラスのコンストラクターで、使わない引数(textViewResourceId)の分 を除いたコンストラクターを作っておく。基本的に、オブジェクトのリストか、オブジェ クトの配列を受け取れるようにすればよい。 public ItemListAdapter(Context context, List<Item> objects) { // (2) public ItemListAdapter(Context context, Item[] objects) { // (4) ArrayAdapter クラスのコンストラクターを呼び出す。このとき、textViewResourceId は 指定されていないので、0 にしておく。 super(context, 0, objects); // (3) (5) 行項目を設定するメソッドのオーバーライド public View getView(int position, View convertView, ViewGroup parent) { // (5) (6)(7) ビューを取得 アプリケーションが起動した直後の状態なんかでは、convertView が null になっている。 このため、LayoutInflater の inflate() メソッドを使って、ビューのオブジェクトを取 得する必要がある。 LayoutInflater layoutInflater = (LayoutInflater) getContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); // (6) convertView = layoutInflater.inflate(R.layout.row, null); // (7) Context.LAYOUT_INFLATER_SERVICE は、レイアウトの動的な描画のために Inflater オブ ジェクトを生成するのに使う定数。 --- View inflate(int resource, ViewGroup root) --- ・LayoutInflater クラス 動的にレイアウトの XML ファイルのオブジェクトを読み込むためのクラス java.lang.Object - android.view.LayoutInflater ・主なメソッド --- View inflate(int resource, ViewGroup root) View inflate(XmlPullParser parser, ViewGroup root) View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) View inflate(int resource, ViewGroup root, boolean attachToRoot) --- (8) position 番目のオブジェクトを取得 getItem() メソッドを使って、リストや配列の position 番目のオブジェクトを取得する。 Item item = getItem(position); // (8) (9)(10) テキストに設定する TextView id = (TextView) convertView.findViewById(R.id.idInList); // (9) id.setText(String.valueOf(item.getId())); // (10) (11) ビューを返す return convertView; // (11) ▲ データベース関係 □ DatabaseHelper.java ※前回のサンプルと同じ ▲エンティティ □ Item.java ※前回のサンプルと同じ ▲レイアウト テーブルの行の一覧を表示するための ListView 要素が追加されている。 □ res/layout/main.xml --- <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:weightSum="1" > <EditText android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/nameHint" > <requestFocus > </requestFocus> </EditText> <EditText android:id="@+id/comment" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/commentHint" android:inputType="textMultiLine" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/findButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="onFindButtonClick" android:text="@string/findButton" /> <Button android:id="@+id/saveButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="onSaveButtonClick" android:text="@string/saveButton" /> <Button android:id="@+id/updateButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="onUpdateButtonClick" android:text="@string/updateButton" /> <Button android:id="@+id/removeButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="onRemoveButtonClick" android:text="@string/removeButton" /> </LinearLayout> <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" /> <!-- (1) --> </LinearLayout> --- (1) リスト・ビュー <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" /> <!-- (1) --> 1 行分のデータは、つぎのファイルで定義している。 □ res/layout/row.xml --- <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/idInList" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/nameInList" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/commentInList" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> --- ▲ 文字列 ※前回のサンプルと同じ 以上