2010年11月19日金曜日

Android Spinner(スピナー)を使用する その4(SimpleAdapter)

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


1,アクティビティのレイアウトにスピナーを追加します。
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>

2,スピナーのレイアウトファイルを作成します。
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"とすること。


3,スピナーのドロップダウンリストのレイアウトファイルを作成します。
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 
 xmlns:android="http://schemas.android.com/apk/res/android" 
 android:id="@+id/text" 
 style="?android:attr/spinnerDropDownItemStyle"
 android:singleLine="true" 
 android:layout_width="fill_parent" 
 android:textSize="14sp"
 android:ellipsize="marquee" 
       android:layout_height="25sp">
</TextView> 
<TextView 
 android:id="@+id/description" 
 style="?android:attr/spinnerDropDownItemStyle"
 android:singleLine="true" 
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:textSize="10sp"
 android:ellipsize="marquee">
</TextView>

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

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

SimpleAdapterクラスのコンストラクタ
SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) 
第1引数contextにはContextオブジェクトを指定します。

第2引数dataにはドロップダウンリストに表示するアイテムを指定します。
ドロップダウンリストに表示するアイテムは、Mapインターフェースを格納したListインターフェースになっています。

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

第4引数fromは第2引数dataで指定したListの要素であるMapから、表示したい要素のキーをString配列で指定します。

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


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

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

MainActivty.java
package my.study.android2;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

public class MainActivity extends Activity {
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
  
        //ドロップダウンデータの作成
        ArrayList<HashMap<String, Object>> items = new ArrayList<HashMap<String, Object>>();
        HashMap<String, Object> map = new HashMap<String, Object>();
        //item1
        map = new HashMap<String, Object>();
        map.put("value",10);
        map.put("text","item1");
        map.put("description","description1");
        items.add(map); 
        //item2
        map = new HashMap<String, Object>();
        map.put("value",20);
        map.put("text","item2");
        map.put("description","description2");
        items.add(map);
        //item3
        map = new HashMap<String, Object>();
        map.put("value",30);
        map.put("text","item3");
        map.put("description","description3");
        items.add(map);
  
        //SimpleAdapterオブジェクトの作成
        SimpleAdapter adapter = new SimpleAdapter(this,items,R.layout.spinner,
                new String[]{"text","description"},
                new int[]{R.id.text,R.id.description});
 
        //ドロップダウンリストのレイアウトを設定します。
        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 arg1, int position, long id) {
                Spinner spinner = (Spinner) parent;
                HashMap<String, Object> item = (HashMap<String, Object>) spinner.getSelectedItem();  
                Toast.makeText(MainActivity.this, item.get("value").toString(), Toast.LENGTH_LONG).show();
            }
            public void onNothingSelected(AdapterView<?> parent) {   
            }
        });
    }
}

ドロップダウンリストにラジオボタンを表示する

上記の方法で表示したスピナーのドロップダウンリストには、選択しているアイテムをチェック状態で表示するラジオボタンが表示されません。これは3で作成したドロップダウンリストのレイアウトファイルの最上位オブジェクトであるLinearLayoutがCheckableインターフェースを実装していないためだそうです。
こちらで詳しく解説されています。
だらだらとだらだら AndroidのAdapterViewで、カスタムビューを使っていてもCheckedTextViewなどのチェックをしたい(Spinnerのdropdown等)

次はドロップダウンリストにラジオボタンを表示したいと思います。

1,まずはCheckableインターフェースを実装したLinearLayoutを作成します。
src/my.study.android.widgets/CheckableLinearLayout.jar
package my.study.android.widgets;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Checkable;
import android.widget.CheckedTextView;
import android.widget.LinearLayout;

public class CheckableLinearLayout extends LinearLayout implements Checkable {
 
    private CheckedTextView mCheckbox;
 
    public CheckableLinearLayout(Context context) {
        super(context);
    }
    public CheckableLinearLayout(Context context, AttributeSet attrs) {        
        super(context, attrs); 
    }
    @Override    
    protected void onFinishInflate() {
        super.onFinishInflate();
        // CheckedTextViewを探します。
        int childCount = getChildCount();
        for (int i = 0; i < childCount; ++i) {
            View v = getChildAt(i);
            if (v instanceof CheckedTextView) {
                mCheckbox = (CheckedTextView)v;   
            }  
        }         
    }
    public boolean isChecked() {
        return mCheckbox != null ? mCheckbox.isChecked() : false;   
    }
    public void setChecked(boolean checked) {
        if (mCheckbox != null) {
            mCheckbox.setChecked(checked);     
        }      
    }

    public void toggle() {
        if (mCheckbox != null) {
            mCheckbox.toggle();     
        }      
    }   
}

2,スピナーのドロップダウンリストのレイアウトファイルを作成します。
res/layout/spinner_dropdown.xml
<?xml version="1.0" encoding="utf-8"?>
<my.study.android.widgets.CheckableLinearLayout 
 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="horizontal"> 
 
<LinearLayout 
 android:id="@+id/LinearLayout02" 
 android:layout_height="wrap_content" 
 android:orientation="vertical" 
 android:layout_width="wrap_content"
 android:layout_weight="1">

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

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

<CheckedTextView 
 android:id="@+id/CheckedTextView01" 
 style="?android:attr/spinnerDropDownItemStyle"
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content">
</CheckedTextView>

</my.study.android.widgets.CheckableLinearLayout>

MainActivity.java、Spinner.xmlの変更はありません。


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

0 件のコメント: