単位換算アプリを作る
役に立たないもんばっかり作って、EclipseとAndroidに慣れる練習の続き。
単位換算というと、ビタミンCの重量をレモンの個数に換算するのが、日本の伝統だ。ということで、今日は、入力した重量が、レモン(のビタミンC)何個分か?に換算するアプリを作ってみることにした*1。
画面レイアウトは以下のような感じで、数値を入力するEditTextと、単位を選択するSpinnerと、実行するボタンがあって、ボタンを押したら回答を表示するTextViewがある。
EditTextに入力できるのは数値だけに限定するために、android:inputType="number"を設定しておいたけれど、これを"numberDecimal"にした場合にどう違うのか、よく分かってない。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:id="@+id/LinearLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:text="" android:id="@+id/EditText01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:width="@dimen/inputAreaWidth" android:inputType="number" /> <Spinner android:layout_width="wrap_content" android:id="@+id/Spinner01" android:layout_height="wrap_content" /> <Button android:text="@string/btn" android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <TextView android:text="" android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
さて、Spinnerコントロールを使えるようにする。Spinnerに表示する中身は、ArrayAdapter型を指定するらしい。
ArrayAdapterに項目を登録するには、add()で一つずつ登録していくか、配列をあらかじめ作っておいて、コンストラクタでそれを指定するかというようにやるらしい。今回は、String[] で配列を作っておいた。
package com.example.lemmon; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; import android.widget.AdapterView; public class UnitConverter extends Activity { private final String[] units = {"kg", "g", "mg"}; private int selectedIndex=0; private final int lemmon = 20; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final Button btn = (Button) findViewById(R.id.Button01); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showMessage(); } }); final Spinner unit = (Spinner) findViewById(R.id.Spinner01); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, units); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); unit.setAdapter(adapter); unit.setSelection(0); unit.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { selectedIndex = position; } public void onNothingSelected(AdapterView<?> parent) { } }); } private String lemmonConvert(String in, int index){ StringBuilder sb = new StringBuilder(); int i = Integer.parseInt(in); switch (index){ case 0: i = i * 1000* 1000; break; case 1: i = i * 1000; break; case 2: //; break; } int res = i / lemmon; sb.append("レモン").append(res).append("個分のビタミンCに相当します。"); return sb.toString(); } private void showMessage() { TextView result = (TextView) findViewById(R.id.TextView01); EditText input = (EditText) findViewById(R.id.EditText01); result.setText(lemmonConvert(input.getText().toString(), selectedIndex)); } }
ここで悩みが。
こうやって、画面上のwidgetが増えていくと、それぞれの部品ごとにListenerを設定して、そのListenerが監視するeventを追記して、、、ってやっていくと、ActivityのonCreate()が、だらだらと長くなってしまう気がするんだけれど、どうすりゃ良いんだろう。やっぱり、設定するwidgetのまとまりごとに、private methodでinit○○みたいなメソッドを大量に作るのが良いのだろうか。
*1:身長や体重をりんごの個数で表すのも一般的なので、そういう拡張もしてみることにする