2012年10月2日火曜日

Android Spinnerで表示する値と実際に使用する内部的な値

Spinnerで表示する値と、実際に使用する内部的な値を変えたい場合の方法です。
いろいろな方法があるようですが、ArrayAdapterを拡張する方法です。

まず内部的な値(Key)と表示する値(Value)のペアとなるクラスを作成しました。
Androidにはキーと値のペアを表すPair<T,T>クラスがあるのですが、 キーはInteger、値はStringという場合がほとんどで、Pair<Integer,String>とイチイチ書くのが面倒なので作っておきます。
このクラスはなくてもいいです。
その場合はKeyValuePairを使用している箇所はPair<Integer,String>と読み替えてください。
public class KeyValuePair extends Pair<Integer,String> {

    public KeyValuePair(Integer key, String value) {
        super(key, value);
    }

    public Integer getKey(){
        return super.first;
    }
    
    public String getValue(){
        return super.second;
    }
}

次にArrayAdapterを継承しKeyValuePairArrayAdapterクラスを作成します。
getViewメソッドでスピナー部分に表示する値を返すようにします。
getDropDownViewメソッドでスピナーのドロップダウンに表示する値を返すようにします。
getPositionメソッドでスピナーに設定した値リストから、内部で使用する値(キー)の要素番号を返すようにします。
    public class KeyValuePairArrayAdapter extends ArrayAdapter<KeyValuePair> {
    
    /**
     * @brief コンストラクタ
     * @param context
     * @param textViewResourceId
     */
    public KeyValuePairArrayAdapter(Context context, int textViewResourceId) {
        super(context, textViewResourceId);
    }
    /**
     * @brief コンストラクタ
     * @param context
     * @param textViewResourceId
     * @param list
     */
    public KeyValuePairArrayAdapter(Context context, int textViewResourceId, List<KeyValuePair> list) {
        super(context, textViewResourceId, list);    
    }
    
    /**
     * @brief Spinerに表示するViewを取得します。
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView view = (TextView) super.getView(position, convertView, parent);
        view.setText(getItem(position).getValue());
        return view;

    }
    /**
     * @brief Spinerのドロップダウンアイテムに表示するViewを取得します。
     */
    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        TextView view = (TextView) super.getDropDownView(position, convertView, parent);
        view.setText(getItem(position).getValue());
        return view;
    }

    /**
     * @brief keyに一致するインデックスを取得します。
     * @param key
     * @return
     */
    public int getPosition(int key){
        int position = -1;
        for (int i = 0 ; i < this.getCount(); i++){
            if (this.getItem(i).getKey() == key) {
                position = i;
                break;
            }
        }
        return position;
        
    }
    
}


実際に使用する際のコードです。

まずはベタっとした場合
public class MainActivity extends Activity {
    
    private Spinner _spinner = null;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //スピナー
        _spinner =  (Spinner)this.findViewById(R.id.spinner1); 
        _spinner.setOnItemSelectedListener(Spinner1_OnItemSelectedListener);
        //スピナーのドロップダウンアイテムを設定
        KeyValuePairArrayAdapter adapter = new KeyValuePairArrayAdapter(this, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        adapter.add(new KeyValuePair(1,"One"));
        adapter.add(new KeyValuePair(2,"Two"));
        adapter.add(new KeyValuePair(3,"Three"));
        _spinner.setAdapter(adapter);
        //キーが2の値を選択する
        Integer selectKey = 2;
        _spinner.setSelection(adapter.getPosition(selectKey));
    }
    
    /**
     * @brief スピナーのOnItemSelectedListener
     */
    private OnItemSelectedListener Spinner1_OnItemSelectedListener = new OnItemSelectedListener() {
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            KeyValuePair item = (KeyValuePair)_spinner.getSelectedItem();   
            Toast.makeText(MainActivity.this, item.getKey().toString(), Toast.LENGTH_LONG).show();       
        }
        public void onNothingSelected(AdapterView<?> arg0) {            
        }  
    };  

}

次はデータベースのデータの場合
public class MainActivity extends Activity {
    
    private Spinner _spinner = null;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //スピナー
        _spinner =  (Spinner)this.findViewById(R.id.spinner1); 
        _spinner.setOnItemSelectedListener(Spinner1_OnItemSelectedListener);
        //スピナーのドロップダウンアイテムを設定
        List<KeyValuePair> list = getSpinnerData();
        KeyValuePairArrayAdapter adapter = new KeyValuePairArrayAdapter(this, android.R.layout.simple_spinner_item, list);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        _spinner.setAdapter(adapter);
        //キーが2の値を選択する
        Integer selectKey = 2;
        _spinner.setSelection(adapter.getPosition(selectKey));
    }

    /**
     * @brief スピナーデータを取得します。
     * @return
     */
    private List<KeyValuePair> getSpinnerData(){
        StringBuilder sql = new StringBuilder(); 
        sql.append(" SELECT Code, Name"); 
        sql.append(" FROM MYTABLE");
                
        List<KeyValuePair> list = new ArrayList<KeyValuePair>();
        DatabaseHelper dbhelper = new DatabaseHelper(this);
        SQLiteDatabase db = dbhelper.getReadableDatabase();
        try {
            Cursor cursor = db.rawQuery(sql.toString(), null);
            cursor.moveToFirst();
            try {
                while (cursor.moveToNext()){   
                    list.add(new KeyValuePair(cursor.getInt(0),cursor.getString(1)));   
                }   
            } finally {
                cursor.close();
            }
        } finally {
            db.close();
        }
        return list;
    }
    /**
     * @brief スピナーのOnItemSelectedListener
     */
    private OnItemSelectedListener Spinner1_OnItemSelectedListener = new OnItemSelectedListener() {
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            KeyValuePair item = (KeyValuePair)_spinner.getSelectedItem();   
            Toast.makeText(MainActivity.this, item.getKey().toString(), Toast.LENGTH_LONG).show();       
        }
        public void onNothingSelected(AdapterView<?> arg0) {            
        }  
    };  

}

最後にリソースで定義したデータの場合
リソース
<?xml version="1.0" encoding="utf-8"?>
<resources>
    
    <!-- Spinner1のドロップダウンアイテム -->
    <string-array name="spinner1_item1"> 
       <item name="key">1</item> 
       <item name="value">One</item> 
    </string-array> 
    <string-array name="spinner1_item2"> 
       <item name="key">2</item> 
       <item name="value">Two</item> 
    </string-array> 
    <string-array name="spinner1_item3"> 
       <item name="key">3</item> 
       <item name="value">Three</item> 
    </string-array> 
    
    <array name="spinner1_data"> 
       <item>@array/spinner1_item1</item> 
        <item>@array/spinner1_item2</item>
        <item>@array/spinner1_item3</item>  
    </array> 

</resources>
アクティビティ
public class MainActivity extends Activity {
    
    private Spinner _spinner = null;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //スピナー
        _spinner =  (Spinner)this.findViewById(R.id.spinner1); 
        _spinner.setOnItemSelectedListener(Spinner1_OnItemSelectedListener);
        //スピナーのドロップダウンアイテムを設定
        List<KeyValuePair> list = getSpinnerData();
        KeyValuePairArrayAdapter adapter = new KeyValuePairArrayAdapter(this, android.R.layout.simple_spinner_item, list);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        _spinner.setAdapter(adapter);
        //キーが2の値を選択する
        Integer selectKey = 2;
        _spinner.setSelection(adapter.getPosition(selectKey));
    }

    /**
     * @brief スピナーデータを取得します。
     * @return
     */
    private List<KeyValuePair> getSpinnerData(){
        List<KeyValuePair> list = new ArrayList<KeyValuePair>();
        Resources res = getResources();
        TypedArray spinner1_data = res.obtainTypedArray(R.array.spinner1_data);         
        for (int i = 0; i < spinner1_data.length(); ++i) { 
            int id = spinner1_data.getResourceId(i, -1); 
            if (id > -1) { 
                String[] item = res.getStringArray(id); 
                list.add(new KeyValuePair(Integer.valueOf(item[0]), item[1]));
            } 
        } 
        spinner1_data.recycle(); 
        return list;
    }
    /**
     * @brief スピナーのOnItemSelectedListener
     */
    private OnItemSelectedListener Spinner1_OnItemSelectedListener = new OnItemSelectedListener() {
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            KeyValuePair item = (KeyValuePair)_spinner.getSelectedItem();   
            Toast.makeText(MainActivity.this, item.getKey().toString(), Toast.LENGTH_LONG).show();       
        }
        public void onNothingSelected(AdapterView<?> arg0) {            
        }  
    };  

}

0 件のコメント: