marunomaruno-memo

marunomaruno-memo

[Android] データの取り扱い - ArrayAdapter

2012年02月21日 | Android
[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>
---


▲ 文字列
※前回のサンプルと同じ

                                                                            以上