単位換算アプリを作る

役に立たないもんばっかり作って、EclipseAndroidに慣れる練習の続き。

単位換算というと、ビタミン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:身長や体重をりんごの個数で表すのも一般的なので、そういう拡張もしてみることにする