やりたいこと
- Spinnerの選択項目にenumを使いたい
- 表示文字列はstrings.xmlのものを使いたい
- 内部的なデータとしてはStringやintを使いたい
準備
便利クラスと、それ用のinterfaceを定義する
ICodeLabel.java
enumに実装させるメソッドのinterfaceです。
public interface ICodeLabel {
/** 内部的なデータとして扱うための文字列を返すメソッドです。 */
String getCode();
/** 表示文字列を返すためのメソッドです。 */
String getLabel(Resources res);
}
CodeLabelAdapter.java
前述のICodeLabelを実装したクラスを表示するためのAdapterです。
public class CodeLabelAdapter extends ArrayAdapter<ICodeLabel> {
@LayoutRes
private int mResource;
@LayoutRes
private int mDropDownResource;
public static CodeLabelAdapter newInstance(Context context, ICodeLabel[] objects, boolean withNullValue) {
if (withNullValue) {
List<ICodeLabel> values = new ArrayList<>();
values.add(null);
values.addAll(Arrays.asList(objects));
return new CodeLabelAdapter(context, android.R.layout.simple_list_item_1, android.R.layout.simple_spinner_dropdown_item, values);
} else {
return new CodeLabelAdapter(context, android.R.layout.simple_list_item_1, android.R.layout.simple_spinner_dropdown_item, objects);
}
}
public static CodeLabelAdapter newInstance(Context context, List<ICodeLabel> objects, boolean withNullValue) {
if (withNullValue) {
List<ICodeLabel> values = new ArrayList<>();
values.add(null);
values.addAll(objects);
return new CodeLabelAdapter(context, android.R.layout.simple_list_item_1, android.R.layout.simple_spinner_dropdown_item, values);
} else {
return new CodeLabelAdapter(context, android.R.layout.simple_list_item_1, android.R.layout.simple_spinner_dropdown_item, objects);
}
}
public CodeLabelAdapter(Context context, @LayoutRes int resource, @LayoutRes int dropDownResource, ICodeLabel[] objects) {
super(context, resource, objects);
mResource = resource;
mDropDownResource = dropDownResource;
}
public CodeLabelAdapter(Context context, @LayoutRes int resource, @LayoutRes int dropDownResource, List<ICodeLabel> objects) {
super(context, resource, objects);
mResource = resource;
mDropDownResource = dropDownResource;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(mResource, null);
}
TextView view = (TextView) convertView.findViewById(android.R.id.text1);
ICodeLabel item = getItem(position);
if (item != null) {
view.setText(item.getLabel(getContext().getResources()));
} else {
view.setText("");
}
return view;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(mDropDownResource, null);
}
TextView view = (TextView) convertView.findViewById(android.R.id.text1);
ICodeLabel item = getItem(position);
if (item != null) {
view.setText(item.getLabel(getContext().getResources()));
} else {
view.setText("");
}
return view;
}
}
enumの実装の例
strings.xmlを準備する
基本的に言語別に普通に作成したら良いです。
values/strings.xml
<resources>
<string name="ordinal_label_first">First</string>
<string name="ordinal_label_second">Second</string>
<string name="ordinal_label_third">Third</string>
<string name="ordinal_label_fourth">Fourth</string>
</resources>
values-ja/strings.xml
<resources>
<string name="ordinal_label_first">ひとつめ</string>
<string name="ordinal_label_second">ふたつめ</string>
<string name="ordinal_label_third">みっつめ</string>
<string name="ordinal_label_fourth">よっつめ</string>
</resources>
OrdinalLabel.java
public enum OrdinalLabel implements ICodeLabel {
FIRST("first", R.string.ordinal_label_first),
SECOND("second", R.string.ordinal_label_second),
THIRD("third", R.string.ordinal_label_third),
FOURTH("fourth", R.string.ordinal_label_fourth),
;
final String code;
@StringRes
final int resId;
OrdinalLabel(String code, @StringRes int resId) {
this.code = code;
this.resId = resId;
}
@Override
public String getCode() {
return code;
}
@Override
public String getLabel(Resources res) {
return res.getString(resId);
}
}
SpinnerへのAdapterの設定の例
// find views
mSpinner = (Spinner) findViewById(R.id.spinner);
// set adapter
mSpinner.setAdapter(CodeLabelAdapter.newInstance(this, OrdinalLabel.values(), true));
サンプルアプリ