スマートフォン・ジン | Smartphone-Zine

引っ越し先→ https://smartphone-zine.com/

Android入門―本気で使える電卓アプリの開発―4

Androidのプロジェクトを作る

まずはAndroidのプロジェクトを作成しましょう。[ファイル]メニューより[新規]-[Android Project]を選択します。 New Android Projectウィンドウが開くので、次の値を設定して、プロジェクトを作成してください。

  • Project name:MyCalc(任意設定)
  • Build Target:Android 1.6
  • Application name:MyCalc(任意設定)
  • Package name:my.android.mycalc(任意設定)
  • Create Activity:MainActivity
  • Min SDK Version:4

Projectが作成されると、srcフォルダに「MainActivity.java」ファイルが作成されていると思います。これが今回のメイン画面になります。電卓なので画面はシンプルにMainActivity1画面のみで構成します。 「MainActivity.java」ファイルを開きましょう。雛形なのでほとんどなにもありません。 setContentView(R.layout.main);という一文があります。これはリソースファイルからmainという画面デザインを読み込むよう指示しています。では画面デザインmainを見ていきましょう。

Androidの画面デザインをXMLで行う

画面デザインは「res/layout」フォルダ内にある「main.xml」というxmlファイルで行います。「main.xml」ファイルを開くと、編集画面になります。下部にあるタブからGraphical Layoutを選ぶとグラフィカルな編集画面になり、main.xlmを選ぶとテキストによる編集画面になります。 タブでmain.xmlを選択してテキスト編集画面を開いてください。LinearLayoutが一つ、そのなかにTextViewが1つ配置されているのが分かると思います。ここに電卓のボタンを配置していきます。 LinerLayoutは、テキストやボタンなどの画面要素を直線的に縦または横に並べるためのレイアウトです。LinerLayoutの中にさらに2つのLinerLayoutを配置してください。 1つ目のLinerLayoutの中にTextViewを1つ配置します。これが電卓の液晶ディスプレイになります。2つ目のLinerLayoutの中には、TableLayoutを配置します。TableLayoutは電卓のボタンを格子状に並べるために使用します。 2つ目のTableLayoutの中には、行を表すTableRowを4つ配置します。各行にはボタンを4つずつ配置してください。 あとはボタンに名前をつけ、液晶ディスプレイの背景色と文字色を変更します。完成した「main.xml」は次のようになりました。

[xml]
<?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/linearLayout1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_vertical|center_horizontal"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/display" android:textSize="40sp" android:textColor="#505050" android:background="#EEEEEE" android:gravity="right"></TextView> </LinearLayout> <LinearLayout android:id="@+id/linearLayout2" android:layout_width="fill_parent" android:orientation="horizontal" android:layout_height="fill_parent"> <TableLayout android:id="@+id/tableLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TableRow android:layout_weight="1" android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/tableRow1"> <Button android:layout_height="fill_parent" android:text="+/-" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/sign" android:layout_margin="5px" android:layout_weight="1" android:minWidth="60dip"></Button> <Button android:layout_height="fill_parent" android:text="7" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/seven" android:layout_margin="5px" android:layout_weight="1" android:minWidth="60dip"></Button> <Button android:layout_height="fill_parent" android:text="8" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/eight" android:layout_margin="5px" android:layout_weight="1" android:minWidth="60dip"></Button> <Button android:layout_height="fill_parent" android:text="9" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/nine" android:layout_margin="5px" android:layout_weight="1" android:minWidth="60dip"></Button> <Button android:layout_height="fill_parent" android:text="歎" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/divide" android:layout_margin="5px" android:layout_weight="1" android:minWidth="60dip"></Button> </TableRow> <TableRow android:layout_weight="1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/tableRow2"> <Button android:layout_height="fill_parent" android:text="C" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/clear" android:layout_margin="5px" android:layout_weight="1"></Button> <Button android:layout_height="fill_parent" android:text="4" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/four" android:layout_margin="5px" android:layout_weight="1"></Button> <Button android:layout_height="fill_parent" android:text="5" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/five" android:layout_margin="5px" android:layout_weight="1"></Button> <Button android:layout_height="fill_parent" android:text="6" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/six" android:layout_margin="5px" android:layout_weight="1"></Button> <Button android:layout_height="fill_parent" android:text="x" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/times" android:layout_margin="5px" android:layout_weight="1"></Button> </TableRow> <TableRow android:layout_weight="1" android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/tableRow3"> <Button android:layout_height="fill_parent" android:text="AC" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/allclear" android:layout_margin="5px" android:layout_weight="1"></Button> <Button android:layout_height="fill_parent" android:text="1" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/one" android:layout_margin="5px" android:layout_weight="1"></Button> <Button android:layout_height="fill_parent" android:text="2" android:onClick="onClickButton" android:layout_width="wrap_content" android:id="@+id/two" android:layout_margin="5px" android:layout_weight="1"></Button> <Button android:layout_height="fill_parent" android:text="3" android:onClick="onClickButton" android:layout_width="wrap_content" android:id="@+id/three" android:layout_margin="5px" android:layout_weight="1"></Button> <Button android:layout_height="fill_parent" android:text="-" android:onClick="onClickButton" android:layout_width="wrap_content" android:id="@+id/minus" android:layout_margin="5px" android:layout_weight="1"></Button> </TableRow> <TableRow android:layout_weight="1" android:layout_height="fill_parent" android:layout_width="wrap_content" android:id="@+id/tableRow4"> <Button android:layout_height="fill_parent" android:text="0" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/zero" android:layout_margin="5px" android:layout_weight="1"></Button> <Button android:layout_height="fill_parent" android:text="00" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/doublezero" android:layout_margin="5px" android:layout_weight="1"></Button> <Button android:layout_height="fill_parent" android:text="." android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/comma" android:layout_margin="5px" android:layout_weight="1"></Button> <Button android:layout_height="fill_parent" android:text="=" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/equal" android:layout_margin="5px" android:layout_weight="1"></Button> <Button android:layout_height="fill_parent" android:text="+" android:onClick="onClickButton" android:layout_width="fill_parent" android:id="@+id/plus" android:layout_margin="5px" android:layout_weight="1"></Button> </TableRow> </TableLayout> </LinearLayout> </LinearLayout>
[/xml]

各ボタンにはandroid:onClick="onClickButton"のようにonClick属性を追加してください。この指定をすることで、ボタンが押されたときにMainActivityクラスのonClickButtonメソッドが呼び出されます。

電卓のベース処理を修正する

さて、これまでに作成した電卓のベース部分では、演算結果を標準出力に表示する仕様でした。これを、先ほどXMLでレイアウトしたTextViewに表示するように変更します。 「StringDisplay.java」のshowDisplayメソッドを修正して、TextViewを更新出来るように変更します。

[java]
public class StringDisplay extends AbstractDisplay {
    private TextView txt;  //  ←追加
    public StringDisplay( TextView disp ) {
        clear();
        this.txt=disp;  //  ←追加
    }
    ・・・省略・・・
    public void showDisplay(boolean format) {
        ・・・省略・・・
        txt.setText(sb);  //  ←追加
    }
・・・省略・・・
[/java]

「Calc.java」では、StringDisplayに更新対象となるTextViewインスタンスを渡すためのメソッドを追加します。

[java]
public void setDisp(TextView txt){
    this.disp = new StringDisplay(txt);
}
[/java]

電卓のベース処理をMainActivity.javaに組み込む

では次にお待ちかねのAndroidのプログラミングを説明していきます。「MainActivity.java」の編集です。電卓のベース処理を組み込み、MainActivityクラスにonClickButtonメソッドを実装してボタンが押されたときの処理を記述していきます。

[java]
public class MainActivity extends Activity {
    Calc calc = new Calc();
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView txtDisp = (TextView) findViewById(R.id.display);
        calc.setDisp(txtDisp);
    }
    public void onClickButton(View view) {
        switch (view.getId()) {
        case R.id.zero:
            calc.onButtonNumber(Number.ZERO);
            break;
        case R.id.doublezero:
            calc.onButtonNumber(Number.DOUBLE_ZERO);
            break;
        case R.id.one:
            calc.onButtonNumber(Number.ONE);
            break;
        case R.id.two:
            calc.onButtonNumber(Number.TWO);
            break;
        case R.id.three:
            calc.onButtonNumber(Number.THREE);
            break;
        case R.id.four:
            calc.onButtonNumber(Number.FOUR);
            break;
        case R.id.five:
            calc.onButtonNumber(Number.FIVE);
            break;
        case R.id.six:
            calc.onButtonNumber(Number.SIX);
            break;
        case R.id.seven:
            calc.onButtonNumber(Number.SEVEN);
            break;
        case R.id.eight:
            calc.onButtonNumber(Number.EIGHT);
            break;
        case R.id.nine:
            calc.onButtonNumber(Number.NINE);
            break;
        case R.id.plus:
            calc.onButtonOp(Operation.PLUS);
            break;
        case R.id.minus:
            calc.onButtonOp(Operation.MINUS);
            break;
        case R.id.times:
            calc.onButtonOp(Operation.TIMES);
            break;
        case R.id.divide:
            calc.onButtonOp(Operation.DIVIDE);
            break;
        case R.id.comma:
            calc.onButtonNumber(Number.COMMA);
            break;
        case R.id.allclear:
            calc.onButtonAllClear();
            break;
        case R.id.clear:
            calc.onButtonClear();
            break;
        case R.id.equal:
            calc.onButtonEquale();
            break;
        case R.id.sign:
            calc.changeSign();
            break;
        default:
            break;
        }
    }
}
[/java]

onClickButtonメソッド内では、switch-case文で押されたボタンを判定して、Calcクラスのメソッドを呼び出しているだけです。 実はAndroid側のコーディングはたったこれだけです。これだけのコーディングでもちゃんと動いてくれます。 では早速実行してみましょう。

どうでしょう!これだけでも十分に電卓としての役目を果たしてくれまています! ただ、まだエラーハンドリングが出来ていませんので、1÷0=と入力すると「Infinity」と表示されてしまいます。また演算結果が12桁以上になり、電卓の表示桁から溢れてしまう場合、上位桁しか表示されませんが、桁あふれしたことが分かりません。これは正しくエラー処理して、ユーザに通知する必要があります。 次からはエラー処理の追加をしていきたいと思います。 今回使用したプロジェクトファイルはこちらからダウンロード出来ます。