Android Spinner(スピナー)を使用する その5(SimpleCursorAdapter)

今回はSimpleCursorAdapterを使用してみました。
SimpleCursorAdapterはxmlファイルで定義された複数のビューに対して、CursorオブジェクトのColumnをマッピングする簡単なアダプターです。



1,データベースにデータを作成します。
Android SQLiteデータベースを作成するで作成したDatabaseHelper.javaを使用し、以下のようなテーブルを作成しました。

CREATE TABLE Categories
(
CategoryID integer NOT NULL,
CategoryName text NOT NULL,
Description text,
primary key(CategoryID)
)

あとはInsert文で適当にデータを追加します。
Android データベースにデータを書き込む(Insert、Update、Delete)


2,アクティビティのレイアウトにスピナーを追加します。
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout 
 android:id="@+id/LinearLayout01" 
 android:layout_width="fill_parent" 
 android:layout_height="fill_parent" 
 xmlns:android="http://schemas.android.com/apk/res/android" 
 android:orientation="vertical">
    
<Spinner 
 android:id="@+id/Spinner01" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content"> 
</Spinner>

</LinearLayout>

3,スピナーのレイアウトファイルを作成します。
res/layout/spinner.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
 xmlns:android="http://schemas.android.com/apk/res/android" 
 android:id="@+id/LinearLayout01" 
 android:layout_width="fill_parent" 
 android:layout_height="fill_parent" 
 android:orientation="vertical">
 
<TextView 
 android:id="@+id/text" 
 style="?android:attr/spinnerItemStyle"
 android:singleLine="true"    
    android:layout_width="fill_parent"    
    android:layout_height="wrap_content"    
    android:textSize="14sp"  
    android:ellipsize="marquee" > 
</TextView>

</LinearLayout>
注意点は
・android:idは3で作成するレイアウトのidと同じにすること。
・規定のスタイルを使用する場合は style="?android:attr/spinnerItemStyle"とすること。

4,スピナーのドロップダウンリストのレイアウトファイルを作成します。
res/layout/spinner_dropdown.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android" 
 android:id="@+id/LinearLayout01" 
 android:layout_width="fill_parent" 
 android:layout_height="fill_parent" 
 android:orientation="vertical"> 

 <TextView 
  android:id="@+id/text" 
  style="?android:attr/spinnerDropDownItemStyle"
  android:layout_width="wrap_content" 
  android:layout_height="25sp"
  android:textSize="14sp">   
 </TextView>

 <TextView 
  android:id="@+id/description" 
  style="?android:attr/spinnerDropDownItemStyle"
  android:layout_width="wrap_content" 
  android:layout_height="20sp"
  android:textSize="10sp">
 </TextView>

</LinearLayout>
注意点は
・android:idは2で作成するレイアウトのidと同じにすること。
・規定のスタイルを使用する場合はstyle="?android:attr/spinnerDropDownItemStyle"とすること。

5,アクティビティクラス
SimpleCursorAdapterクラスを使用してスピナーの設定を行います。

SimpleCursorAdapterクラスのコンストラクタ
SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) 
第1引数contextにはContextオブジェクトを指定します。

第2引数layoutはスピナーに使用するレイアウトファイルのIDを指定します。
今回は3で作成したレイアウトファイルを指定します。

第3引数cにはドロップダウンリストに表示するアイテムを指定します。
ドロップダウンリストに表示するアイテムは、データベースから取得したデータのCursorオブジェクトです。
Cursorオブジェクトに「_id」フィールドが含まれていないとエラーになります。

第4引数fromは第3引数で指定したCursorオブジェクトから、表示したいカラム名をString配列で指定します。

第5引数toは第4引数fromで指定したカラムの値をを表示するレイアウトファイル内のViewのIdをint配列で指定します。

またSimpleCursorAdapter#setDropDownViewResource()メソッドでドロップダウンリスト部分に使用するレイアウトファイルのIDを指定します。
既定のレイアウトを使用する場合は、アンドロイドで定義されているandroid.R.layout.simple_spinner_dropdown_itemを指定します。
今回は4で作成したレイアウトファイルを指定します。

あとは作成したAdapterオブジェクトを、Spinner#.setAdapter()メソッドでスピナーに設定します。


データベースのデータを取得するにはAndroid データベースのデータを読み込む(Select)を参考にしてください。

またSimpleCursorAdapterのコンストラクタ引数に指定するCursorオブジェクトには「_id」フィールドが含まれていないとエラーになります。データベースのテーブルに「_id」フィールドを用意するか、SELECT文で「_id」フィールドを追加してください。

今回はSELECT文で「_id」フィールドを追加しました。
package my.study.android;

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.SimpleCursorAdapter;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

public class MainActivty extends Activity {
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        //データベースよりデータを取得します
        DatabaseHelper dbHelper = new DatabaseHelper(this);      
        SQLiteDatabase db = dbHelper.getReadableDatabase();  
        String sql = "SELECT '0' AS _id, CategoryID, CategoryName, Description " +
                     "FROM Categories";
        Cursor cursor = db.rawQuery(sql,null);
        //Adapterを作成します。
        String[] from = {"CategoryName","Description"};
        int[] to = {R.id.text,R.id.description};
        SimpleCursorAdapter adapter = 
            new SimpleCursorAdapter(this,R.layout.spinner,cursor,from,to);
        //ドロップダウンリストのレイアウトを設定します。   
        adapter.setDropDownViewResource(R.layout.spinner_dropdown);   
        //スピナーにadapterを設定します。   
        Spinner spinner  = (Spinner)this.findViewById(R.id.Spinner01);   
        spinner.setAdapter(adapter);
        //スピナーのアイテムが選択された時に呼び出されるコールバックリスナーを登録します   
        spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
            public void onItemSelected(AdapterView parent, View view, int position, long id) {
                Spinner spinner = (Spinner) parent;   
                Cursor cursor = (Cursor)spinner.getSelectedItem();
                int categoryId = cursor.getInt(cursor.getColumnIndex("CategoryID"));
                Toast.makeText(MainActivty.this,
                    Integer.valueOf(categoryId).toString(),
                    Toast.LENGTH_LONG).show(); 
            }
            public void onNothingSelected(AdapterView parent) {    
            }   
        });   
    }
}


上記の方法で表示したスピナーのドロップダウンリストには、選択しているアイテムをチェック状態で表示するラジオボタンが表示されません。これは4で作成したドロップダウンリストのレイアウトファイルの最上位オブジェクトであるLinearLayoutがCheckableインターフェースを実装していないためだそうです。
ドロップダウンリストにラジオボタンを表示するには前回の記事Android Spinner(スピナー)を使用する その4(SimpleAdapter)を参考にしてください。


【関連項目】
Android Spinner(スピナー)を使用する その1
Android Spinner(スピナー)を使用する その2(ArrayAdapter)
Android Spinner(スピナー)を使用する その3(UIカスタマイズ)
Android Spinner(スピナー)を使用する その4(SimpleAdapter)
Android Spinner(スピナー)を使用する その5(SimpleCursorAdapter)

1 件のコメント:

匿名 さんのコメント...

これを基に、データを作ったのですが、スピナー選択後、エラーが発生いたしました。