LoginSignup
8
5

More than 5 years have passed since last update.

Spinnerにenumを使いたいときのアプローチ

Last updated at Posted at 2016-05-02

やりたいこと

  • 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));

サンプルアプリ

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5