marunomaruno-memo

marunomaruno-memo

[Android] 簡易電卓アプリ

2012年04月02日 | Android
[Android] 簡易電卓アプリ
================================================================================

単純な機能の電卓アプリ。
つぎのように、単純な機能しか持たない。
    ・ひとつの演算子に対して必ず「=」を押す
    ・連続して複数の演算子を使えない
    ・「=」の後も続けて計算はできない

Android アプリケーションを作るときの基本的な要素しか使っていない。
    LinearLayout
    TextView
    Button

ボタン押下時のハンドラーも、android:onClick 属性で指定している。
    onNumberButtonClick      0 ~ 9 の数字ボタンをクリックしたとき
    onOperatorButtonClick    演算子のボタンをクリックしたとき
    onClearButtonClick       クリア・ボタンをクリックしたとき
    onEqualButtonClick       「=」ボタンをクリックしたとき


▲ レイアウト

4x4 を、LinearLayout と android:layout_weight を使って実現している。

□ res/layout/main.xml
---
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/RESULT_VIEW"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="0"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/NUMBER_BUTTON7"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onNumberButtonClick"
            android:text="7"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Button
            android:id="@+id/NUMBER_BUTTON8"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onNumberButtonClick"
            android:text="8"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Button
            android:id="@+id/NUMBER_BUTTON9"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onNumberButtonClick"
            android:text="9"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Button
            android:id="@+id/DIVIDE_BUTTON"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onOperatorButtonClick"
            android:text="÷"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/NUMBER_BUTTON4"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onNumberButtonClick"
            android:text="4"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Button
            android:id="@+id/NUMBER_BUTTON5"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onNumberButtonClick"
            android:text="5"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Button
            android:id="@+id/NUMBER_BUTTON6"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onNumberButtonClick"
            android:text="6"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Button
            android:id="@+id/MULTIPLY_BUTTON"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onOperatorButtonClick"
            android:text="×"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/NUMBER_BUTTON1"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onNumberButtonClick"
            android:text="1"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Button
            android:id="@+id/NUMBER_BUTTON2"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onNumberButtonClick"
            android:text="2"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Button
            android:id="@+id/NUMBER_BUTTON3"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onNumberButtonClick"
            android:text="3"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Button
            android:id="@+id/SUBTRACT_BUTTON"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onOperatorButtonClick"
            android:text="-"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/NUMBER_BUTTON0"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onNumberButtonClick"
            android:text="0"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Button
            android:id="@+id/CLEAR_BUTTON"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onClearButtonClick"
            android:text="C"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Button
            android:id="@+id/EQUAL_BUTON"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onEqualButtonClick"
            android:text="="
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Button
            android:id="@+id/ADD_BUTTON"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="onOperatorButtonClick"
            android:text="+"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    </LinearLayout>

    <TextView
        android:id="@+id/GUID_VIEW"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/guide" />

</LinearLayout>
---

---
★ @+id でつける名前だが、R クラスでは public static final int で宣言されている
ので、通常の Java の定数のように、すべて大文字で記述したほうがよいように思える。
アクティビティなんかで、switch-case を使っていると、大文字のほうがしっくりくる感
じだ。
---


▲ アクティビティ


□ Calculator01Activity.java
---
package jp.marunomaruno.android.calculator;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import jp.marunomaruno.android.calculator.R;

/**
 * 簡易電卓のアクティビティ。
 * @author marunomaruno
 *
 */
public class Calculator01Activity extends Activity {
    private int number = 0;    // 入力された数字
    private int result = 0;    // 計算結果
    private int operatorId;    // 演算子のリソースID

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    /**
     * 数字のボタンがクリックされたときのハンドラー。
     * @param view
     */
    public void onNumberButtonClick(View view) {
        Button button = (Button) view;
        number = number * 10 + Integer.parseInt(button.getText().toString());
        show(number);
    }

    /**
     * 演算子のボタンがクリックされたときのハンドラー。
     * @param view
     */
    public void onOperatorButtonClick(View view) {
        operatorId = view.getId();
        result = number;
        number = 0;
    }

    /**
     * 「=」ボタンがクリックされたときのハンドラー。
     * @param view
     */
    public void onEqualButtonClick(View view) {
        switch (operatorId) {
        case R.id.ADD_BUTTON:
            result += number;
            break;

        case R.id.SUBTRACT_BUTTON:
            result -= number;
            break;

        case R.id.MULTIPLY_BUTTON:
            result *= number;
            break;

        case R.id.DIVIDE_BUTTON:
            result /= number;
            break;

        default:
            assert false;
            break;
        }

        number = 0;
        show(result);
    }

    /**
     * クリア・ボタンがクリックされたときのハンドラー。
     * @param view
     */
    public void onClearButtonClick(View view) {
        number = 0;
        result = 0;
        operatorId = 0;
        show(number);
    }

    /**
     * 指定された数値を表示する。
     * @param number 表示する数値
     */
    private void show(int number) {
        TextView resultView = (TextView) findViewById(R.id.RESULT_VIEW);
        resultView.setText(Integer.toString(number));
    }
}
---


▲ リソース

□ res/values/strings.xml
---
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">簡易電卓</string>
    <string name="guide">
            ・ひとつの演算子に対して必ず「=」を押す¥n
            ・連続して複数の演算子を使えない¥n
            ・「=」の後も続けて計算はできない¥n
    </string>
</resources>
---


■ 発展

つぎのようなことを考慮して、改良する。
    ・レイアウトを整える
    ・演算子を連続して使えるようにする
    ・「=」の後に続けて演算子を使えるようにする
    ・式も表示できるようにする
    ・他の演算子(平方根や三角など)をつけて、関数電卓にする
    ・16進数が使えるようにする
    ・結果がlong型まで大丈夫にする
    ・数値の桁数の制限をなくす
    ・入力に対して undo する
    ・画面の縦横が変わっても、計算結果を失わないようにする
    ・例外を出さないようにする

                                                                            以上