SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine(コードジン) DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

サンプルアプリでおぼえる実践的Android入門

~実用的な電卓アプリを作る

新しい状態(State)を追加する

 まだ電卓にはエラー処理が実装されていません。例えば1÷0=と入力すると「Infinity」と表示されてしまいます。桁あふれのエラー処理もないため、桁あふれしたことが分かりません。

 また、エラーが発生した場合にはAC(All Clear)ボタン以外受け付けないように制御したいとおもいます。そのためには新しい状態(State)を追加します。

 新しい状態(State)を追加するのは簡単です。Stateインターフェースを実装したクラスを追加します。そしてAC(All Clear)ボタンが押されたときにエラーをクリアするように実装します。

ErrorState.java
public class ErrorState implements State {
    private static ErrorState singleton = new ErrorState();

    private ErrorState() { // コンストラクタはprivate
    }

    public static State getInstance() { // 唯一のインスタンスを得る
        return singleton;
    }

    @Override
    public void onInputNumber(Context context, Number num) {
    }

    @Override
    public void onInputOperation(Context context, Operation op) {
    }

    @Override
    public void onInputEquale(Context context) {
    }

    @Override
    public void onInputClear(Context context) {
    }

    @Override
    public void onInputAllClear(Context context) {
        context.clearA();
        context.clearB();
        context.clearDisplay();
        context.clearError();
        context.changeState(NumberAState.getInstance());
    }
}

 あとは、演算時のエラーを検出したらExceptionを継承したCalcExceptionをスローするように変更します。

Calc.java
    public double doOperation() throws CalcException{
        double result = op.eval(A, B);

        // Doubleの場合、ゼロ割でエラーが発生しないので注意が必要。
        if (Double.isInfinite(result) || Double.isNaN(result)) {
            throw new CalcException();
        }       

        showDisplay(result);

        // 演算結果がディスプレイからはみ出ないかチェック
        if (disp.isOverflow(result)) {
            throw new CalcException();
        }

        return result;
    }

 上記変更により、CalcクラスのdoOperation()メソッドを呼び出している箇所がエラーになるので、try-catch文でErrorStateへ遷移するように変更します。

NumberBState.java
    public void onInputOperation(Context context, Operation op) {
        try {
            context.saveDisplayNumberToB();
            context.doOperation();
            context.setOp(op);
            context.saveDisplayNumberToA();
            context.changeState(OperationState.getInstance());
        } catch (CalcException e) {
            context.setError();
            context.changeState(ErrorState.getInstance());
        }
    }

 そのほかのdoOperation()メソッドを呼び出している箇所も同様に修正します。

 修正は以上です。 実際に動かしてみましょう。例えばゼロ割である1÷0=や、桁溢れする9999999×9999999=などを計算してみてください。ErrorStateに遷移するのでACボタン以外反応しなくなることが分かると思います。

 どうでしょうか。簡単にエラー状態が追加できることが理解できたかと思います。

トースト通知の追加

 電卓アプリ内部ではErrorStateによりエラー状態であることが分かりますが、Androidアプリ上ではエラーになったことが分かりません。そこでAndroidの通知機能「トースト」を使用してエラーを通知するように機能を追加します。

 トーストとは前面に表示される通知のことです。画面の下方に表示され、自動でフェードイン、フェードアウトされます。トースト表示中も現在の画面が見えたままなので、アプリケーションの操作も可能です。

 トーストの表示自体は大変簡単です。Calcクラスに追加しましょう。トースト表示用にContextを保持できるようにメンバ変数parentを追加します。setDispメソッドでContextを受け取りparentに設定することにします。

    // Toast表示用にcontextを持つ。
    protected android.content.Context parent;

    public void setDisp(TextView txt,android.content.Context parent){
        this.disp = new StringDisplay(txt);
        this.parent = parent;
    }

 MainActivityクラスのsetDisp呼び出しも修正しておきます。

calc.setDisp(txtDisp,this);

 トーストを表示するにはToast クラスを使用します。

    public void setError() {
        if (parent != null){
            Toast.makeText(parent, "ERROR", Toast.LENGTH_LONG).show();
        }
        disp.setError();
    }

 実行してみましょう。演算エラーになる操作を行うとERRORの文字が表示されます。

次のページ
AndroidのボタンデザインをXMLで変更する

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

金田 浩明(カネダ ヒロアキ)

ソフトウェア開発者。分析・設計・実装なんでもあり。システム開発をしたり情報処理技術を研究したりスマートフォン開発したりと色々やっています。最近はiPhone,Andoridでの画像認識の仕事に没頭中。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/5957 2011/06/14 14:00

おすすめ

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー