再び単位換算アプリを作ってみる
単位換算アプリを作る - fukuitの日記の続き。例のネコにならって、AppInventorを使ってみる - fukuitの日記で作りかけた、身長と体重をりんごの個数に換算するアプリを作ってみる。
今回、チャレンジするのは、ListViewの扱い。sqldbに保存したデータをListViewでアレコレするsampleはNotePad tutorialに有るんだけれど、ちょっとアレって盛りだくさんな感じがして、オレの理解が追いつかない。
そういうワケで、入力されたデータは永続化されないけれど、まあサンプルですから。お勉強ですから。
layout/main.xml
身長と体重を入力するEditTextは上下に並べて、実行するボタンはその横に並べて、さらに、その下にListViewを配置したい。だから、LinearLayoutを多重に配置してみた。やり方としてこれで良いのかどうかは不明。だいたい、こんな感じ。
<?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/LinearLayout04" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <LinearLayout android:id="@+id/LinearLayout03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:id="@+id/LinearLayout01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:text="@string/height" android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:typeface="monospace" /> <EditText android:text="@string/height_init" android:id="@+id/height" android:layout_width="@dimen/inputAreaWidth" android:layout_height="wrap_content" android:typeface="monospace" android:inputType="number" /> <TextView android:text="@string/height_unit" android:id="@+id/TextView03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:typeface="monospace" /> </LinearLayout> <LinearLayout android:id="@+id/LinearLayout02" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:text="@string/weight" android:id="@+id/TextView02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:typeface="monospace" /> <EditText android:text="@string/weight_init" android:id="@+id/weight" android:layout_width="@dimen/inputAreaWidth" android:layout_height="wrap_content" android:typeface="monospace" android:inputType="number" /> <TextView android:text="@string/weight_unit" android:id="@+id/TextView04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:typeface="monospace" /> </LinearLayout> </LinearLayout> <Button android:text="@string/btn" android:id="@+id/exec_btn" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> <ListView android:id="@android:id/list" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scrollbars="vertical" android:scrollbarStyle="outsideInset" android:smoothScrollbar="true" /> <TextView android:id="@android:id/empty" android:text="@string/no_list" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
values/strings.xmlとvalues/dimens.xml
ということで、layout.xmlの中で呼んでいるリソースを以下のように。
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, KittyCounter!</string> <string name="app_name">KittyCounter</string> <string name="btn">換算</string> <string name="height">身長</string> <string name="weight">体重</string> <string name="height_unit">cm</string> <string name="weight_unit">kg</string> <string name="height_init">180</string> <string name="weight_init">75</string> <string name="no_list">No Data.</string> <string name="menu_delete">削除</string> </resources>
<?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="inputAreaWidth">160sp</dimen> </resources>
こうやってxmlファイルとはいえ、日本語埋め込みだったりとか決め打ちで160spとか書いちゃってるのは気持ち悪いけど、お勉強だからいいのだ。
KittyItem.java
このclass名には問題がある気もするけれど、ソレはサテオクとして、身長と体重を保持するclassを作っておく。setterで入力された身長・体重をりんごの個数に変換しておくようにする。
package com.example.kitty; public class KittyItem { private final double apple_weight=0.300; private final double apple_height=10.0; private double weight; private double height; private int convertedWeight; private int convertedHeight; public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; this.convertedWeight = (int)(weight/this.apple_weight); } public double getHeight() { return height; } public void setHeight(double height) { this.height = height; this.convertedHeight = (int)(height/this.apple_height); } public KittyItem(double weight, double height) { super(); this.weight = weight; this.height = height; this.convertedWeight = (int)(weight/this.apple_weight); this.convertedHeight = (int)(height/this.apple_height); } public KittyItem() { super(); this.weight = 0.0; this.height = 0.0; this.convertedWeight=0; this.convertedHeight=0; } public String toString(){ StringBuilder sb = new StringBuilder(); sb.append("身長: りんご").append(this.convertedHeight).append("個分 / 体重: りんご").append(this.convertedWeight).append("個分"); return sb.toString(); } }
また、日本語埋め込みだけど(以下略)。
KittyCounter.java
まず、ListViewを楽して使うために、メインのactivityをListActivityを継承することにする。
で、ArrayAdapter
KittyItemにはtoString()で、身長・体重をりんごの個数で表すようにしてあるから、ListViewのItemをclickしたら実際の身長・体重をToastで表示するようにしてみた。あとは、ContextMenuで削除するようにもしてみた。
package com.example.kitty; import android.app.ListActivity; import android.os.Bundle; import android.view.ContextMenu; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ContextMenu.ContextMenuInfo; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.Toast; import android.widget.AdapterView.AdapterContextMenuInfo; public class KittyCounter extends ListActivity { private ArrayAdapter<KittyItem> adapter; private static final int DELETE_ID = Menu.FIRST + 1; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); adapter = new ArrayAdapter<KittyItem>(this, android.R.layout.simple_list_item_1); setListAdapter(adapter); final Button btn = (Button) findViewById(R.id.exec_btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { doCalculate(); } }); registerForContextMenu(getListView()); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { KittyItem item = (KittyItem)l.getAdapter().getItem(position); StringBuilder sb = new StringBuilder(); sb.append("身長:").append(item.getHeight()).append("cm / 体重:") .append(item.getWeight()).append("kg"); Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show(); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); menu.add(0, DELETE_ID, 0, R.string.menu_delete); } @Override public boolean onContextItemSelected(MenuItem item) { switch(item.getItemId()) { case DELETE_ID: AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); KittyItem kitty = (KittyItem)getListView().getAdapter().getItem(info.position); adapter.remove(kitty); return true; } return super.onContextItemSelected(item); } private void doCalculate() { EditText hEdit = (EditText) findViewById(R.id.height); EditText wEdit = (EditText) findViewById(R.id.weight); double h = Double.parseDouble(hEdit.getText().toString()); double w = Double.parseDouble(wEdit.getText().toString()); adapter.add(new KittyItem(w, h)); } }
ということで、ひとまず、エミュレータ上で動くことは確認した。ListViewって、android.R.layout.simple_list_item_1で使う分には、簡単だな。