00. はじめに
例えば、「android spinner」みたいにググると配列を使用する例が主に出てきます。
しかしながら、 spinner に表示した内容を(少なくとも僕は)そのまま使うことは少なく、表示した内容に対応した値を使用したりします。
その場合、配列より enum 使った方が良くね?って話です。
01. こんな例を考える
spinner で果物を選択し、ボタンを押すと色を表示するといった簡単なものです。
02. 配列だとこんな感じ
public class MainActivity extends AppCompatActivity {
private static final String[] FRUIT = {
"Apple",
"Banana",
"Kiwi fruit",
"Lemon",
"Orange"
};
private static final String TEXT_FORMAT = "%s is %s";
private Spinner mSpinner = null;
private TextView mTextView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSpinner = findViewById(R.id.spiner);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, FRUIT);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(adapter);
Button button = findViewById(R.id.button);
button.setOnClickListener(mClickListener);
mTextView = findViewById(R.id.textView);
}
private View.OnClickListener mClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
String color;
switch ((String) mSpinner.getSelectedItem()) {
case "Apple":
color = "Red";
break;
case "Banana":
color = "Yellow";
break;
case "Kiwi fruit":
color = "Green";
break;
case "Lemon":
color = "Yellow";
break;
case "Orange":
color = "Orange";
break;
default:
color = "";
break;
}
mTextView.setText(String.format(Locale.US, TEXT_FORMAT, mSpinner.getSelectedItem(), color));
}
};
}
これの問題点は2つあると思います。
- 配列に要素を追加した場合、 OnClickListener に分岐を追加しないといけない
- 配列の要素と値の対応が離れているため対応関係が分かりづらい
03. enum だとこうなる
public class MainActivity2 extends AppCompatActivity {
private enum FRUIT {
APPLE("Apple", "Red"),
BANANA("Banana", "Yellow"),
KIWI_FRUIT("Kiwi fruit", "Green"),
LEMON("Lemon", "Yellow"),
ORANGE("Orange", "Orange");
String fruit;
String color;
FRUIT(String fruit, String color) {
this.fruit = fruit;
this.color = color;
}
@Override
public String toString() {
return fruit;
}
}
private static final String TEXT_FORMAT = "%s is %s";
private Spinner mSpinner = null;
private TextView mTextView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSpinner = findViewById(R.id.spiner);
ArrayAdapter<FRUIT> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, FRUIT.values());
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(adapter);
Button button = findViewById(R.id.button);
button.setOnClickListener(mClickListener);
mTextView = findViewById(R.id.textView);
}
private View.OnClickListener mClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
mTextView.setText(String.format(Locale.US, TEXT_FORMAT,
((FRUIT) mSpinner.getSelectedItem()).fruit,
((FRUIT) mSpinner.getSelectedItem()).color));
}
};
}
どうでしょう?
要素を追加しても処理に修正を加える必要がなく、対応関係も分かりやすくなっていると思います。
toString() を Override しておけば表示内容も問題なく任意の内容にできます。
04. 動的に変更するなら大人しくクラスを作るべき
今回の話は背景色設定などでパターンを選択してもらう場合の話です。
ユーザーの入力内容を spinner に表示するなど動的に変更させる場合、クラスを作った方が良いです。
(というか、配列と条件分岐じゃ無理だと思う)
99. 更新履歴
日付 | 内容 |
---|---|
2018/07/01 | 投稿 |