アプリ開発初心者の暇つぶしAndroid体験記

アプリ開発初心者がAndroidアプリ開発始めました。日々学んだことをアウトプットしていきます。

drawableリソースのselecterについてまとめてみた

今回は画面の見た目について記事にしていきます。

drawableリソースのselecterというものが興味深かったので今回の題材にします。
それではどうぞ!

selecterとは

このselecterを使うことによって、
そのパーツの状態によってデザインを変えることができるようになります。
例えば、カーソルがあたった時や、クリックされた時です。

どんな状態の時に変えられる?

代表的なものをあげるとこのような状態の時に変えることができます。

これらの状態の時にそれぞれ色や形をかえることができます。

設定方法は?

では実際に設定する方法を見ていきます。
まずはdrawableリソースを書いていきます。

[button_layout.xml]

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" >
        <shape>
            <solid android:color="#ff7f50" />
        </shape>
    </item>

    <item android:state_focused="true" >
        <shape>
            <solid android:color="#000080" />
        </shape>
    </item>

    <item>
        <shape>
            <solid android:color="#a9a9a9" />
        </shape>
    </item>
</selector>

itemタグのstate_XXXX属性がそれぞれどの状態であるかを指しています。
上から、クリック時、フォーカス時、デフォルトです。

作成したファイルをlayoutに適応させます。

[activity_main.xml]

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button"
    android:background="@drawable/button_layout"/>

動作確認

実装したアプリを動かしてみます。

  • デフォルト時

f:id:mtnanao:20200303145509p:plain

  • クリック時

f:id:mtnanao:20200303145331p:plain

  • フォーカス時

f:id:mtnanao:20200303145320p:plain


button_layout.xmlに定義した内容に合わせて色が変わっていくのが分かりますね。


それではselecterに関するまとめは以上です。
お疲れさまでした!!



最後にアプリの宣伝させてください(*^-^*)

play.google.com

NumberPickerを使って数字選択ダイアログを実装してみる

今回はNumberPickerを使って
ダイアログ上にピッカーを配置していきます。

電卓に新機能として割引計算機能を追加します。
ボタンの追加、イベントリスナーの追加は前回記事と同じなので省略します。
xprogrammingx.hatenablog.com

それではやっていきます。

1. ダイアログ用のレイアウトxmlを作成

ダイアログのレイアウトを定義するxmlファイルを新規に作成します。
sale_dialog.xmlというファイル名にしました。
f:id:mtnanao:20200229193416p:plain

2. NumberPickerを定義する

作成したsale_dialog.xmlにNumberPickerを定義していきます。

<NumberPicker
    android:id="@+id/numberPicker1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

これだけでピッカーが配置できます。

3. SaleDialogFragmentクラスの作成

SaleDialogFragmentを新規に作成します。

public class SaleDialogFragment extends DialogFragment {

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        LayoutInflater inflater =  getActivity().getLayoutInflater();
        View view = inflater.inflate(R.layout.sale_dialog, null, false);

        final NumberPicker np1 = (NumberPicker) view.findViewById(R.id.numberPicker1);
        np1.setMinValue(0);
        np1.setMaxValue(9);

        final NumberPicker np2 = (NumberPicker) view.findViewById(R.id.numberPicker2);
        np2.setMinValue(0);
        np2.setMaxValue(9);

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("割引率");
        builder.setPositiveButton("決定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

                MainActivity mainActivity = (MainActivity) getActivity();

                int rate = Integer.parseInt(String.valueOf(np1.getValue()) + String.valueOf(np2.getValue()));
                mainActivity.calcSale(rate);

            }
        });
        builder.setView(view);
        return builder.create();

    }
}

NumberPicker#setMaxValueとNumberPicker#setMinValueを使って、
ピッカーの最大値と最小値を設定しています。
今回は割引率を2桁で示すため1~9のピッカーを2つ並べています。

決定ボタンが押された時の処理をonClickのインナーメソッドに書いていきます。
MainActivutyクラス側にcalcSaleメソッドを準備し、
入力された割引率を引数にそのメソッドを呼び出します。

4. 動作確認

それでは動かしてみます。
f:id:mtnanao:20200229195710p:plain
2000を入力して"割引"ボタンを押します。

f:id:mtnanao:20200229195719p:plain
ピッカーが2つ並んだダイアログが表示されましたね!
30%OFFの計算をしてみます。

f:id:mtnanao:20200229195737p:plain
計算結果も大丈夫そうです。


それでは今回はここまでです(^^)/
お疲れさまでした♪


最後にアプリの宣伝させてください(*^-^*)

play.google.com

DialogFragmentを使ってダイアログ表示と消費税計算処理実装!

今回はDialogFragmetでダイアログを扱ってみようと思います!

作った電卓アプリにダイアログを使った消費税計算機能を追加していきます。

1. ダイアログ表示用のボタンを配置

ダイアログを表示するためのボタンを配置していきます。
f:id:mtnanao:20200227221455p:plain

今回は消費税ボタンを追加しました!
8%か10%かをダイアログから選択できるようにしていきたいと思います。

2. ボタンからダイアログ表示処理を実装

消費税ボタンが押された場合にダイアログを表示するように実装をしていきます。

MainActivity#onCreateメソッド

追加したボタンに対してイベントリスナーを設定します。

findViewById(R.id.tax).setOnClickListener(this);

MainActivity#onClickメソッド

onClickメソッドには消費税ボタンが押された場合の処理を書いていきます。
ここで出てくるTaxDialogFragmentクラスについては後述します!

// 消費税が押された場合の処理
case R.id.tax:

    DialogFragment taxDialog = new TaxDialogFragment();
    FragmentManager manager = getSupportFragmentManager();
    taxDialog.show(manager, "tax");

    break;

TaxDialogFragment内で実装したダイアログをshowで表示しています。

TaxDialogFragmenクラス

今回新規に作成したTaxDialogFragmentクラスになります。

public class TaxDialogFragment extends DialogFragment {

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {

        CharSequence[] taxPercent = {"8%", "10%"};
        Activity activity = getActivity();

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setItems(taxPercent, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

                MainActivity mainActivity = (MainActivity) getActivity();
                switch(which){

                    // 8%が押された場合は、calcTaxメソッドに"8"を渡す
                    case 0:

                        mainActivity.calcTax("8");
                        break;

                    // 10%が押された場合は、calcTaxメソッドに"10"を渡す
                    case 1:

                        mainActivity.calcTax("10");
                        break;
                }
            }
        });
        return builder.create();
    }
}

AlertDialog.Builder#setItemsにダイアログに表示したいリストを設定し、それぞれ選択された場合の処理を実装しています。
今回は選択肢として8%と10%を用意しています。
case文における判断は、設定した配列の何番目かで分岐させます。
呼び出し元のMainActivity#calcTaxで消費税計算と画面表示をしています。

MainActivity#calcTaxメソッド

消費税計算処理です。

public void calcTax(String tax){
    if (tax.equals("8")) {
        resultNum = Math.floor(Double.parseDouble(tmpCalcNum) * 1.08);

    } else if (tax.equals("10")) {
        resultNum = Math.floor(Double.parseDouble(tmpCalcNum) * 1.10);
    }

    viewNum = calc.getText().toString().replaceAll(tmpCalcNum + "$", resultNum.toString()).replace(".0", "");

    tmpCalcNum = resultNum.toString().replace(".0", "");;
    calc.setText(viewNum);
}

受け取った引数を元に消費税計算と表示です。
計算後の小数点以下は切り捨てます。

3. 動作確認

それでは動かして確認してみます!
f:id:mtnanao:20200229113645p:plain

100を入力して消費税ボタンを押すと、ダイアログが出てきました。
8%を押してみます。

f:id:mtnanao:20200229113731p:plain

108になりました!
ここから続けて演算することもできました(^^)/


それでは今回はここまでです!
お疲れさまでした♪

電卓を作ろう【デバッグ編】

今回は色々と動かして気になったところを直しました!
Android Studioを使ったデバッグ方法を紹介します!

修正ソースを載せようか迷いましたが、細かすぎるのでやめました。汗
それではやっていきます!

1. デバッグモードでのアプリ起動

まずはアプリをデバッグモードで起動します。
ツールバーの[実行] -> [デバッグ] を選択することで
アプリがデバッグモードで起動します。

2. ブレークポイントの設定

デバッグモードで動作しているアプリを、処理の途中で止めるためにブレークポイントなるものを設定します。
止めたいコードの枠外(行数表示の右)をクリックすると赤い丸が表示されます。
これがブレークポイントです。
f:id:mtnanao:20200226231354p:plain

3. デバッグ作業

それでは、ブレークポイントを通過するようにアプリを動かしてみましょう!
すると、このようにブレークポイントの位置でアプリが停止します。
f:id:mtnanao:20200226231849p:plain

右下に変数ウィンドウが表示されており、
止まった時点での各変数に格納されている値を見ることができます。

とまった位置からアプリを1行ずつ(ステップ実行)することもできます。
良く使うのは「ステップオーバー」(F8キー)でしょうか。
階層は変えず、そのまま次の行に進みます。こんな感じですね。
f:id:mtnanao:20200226232350p:plain

他にも、階層を1つ下る「ステップイン」や、
階層を1つ上る「ステップアウト」などもあります。

また、F9キーを押すことで次のブレークポイントにぶつかるまで処理をとばすことができます。
ブレークポイントを複数おいて、ポイントポイントで動きを確認したい時はF9キーで進んだほうが効率的ですね!


それでは今回はここまでとします!
お疲れさまでした!!

電卓を作ろう【クリア処理実装編】

今回はクリア処理の実装を行っていきます!

メインの計算処理は前回の記事をご覧ください!
それではやっていきましょう!

1. Cボタンの実装

今回の電卓ではCボタンは末尾の一文字を消す処理とします。
大きく、演算記号を消した時と数字を消した時で動きが変わります。
では、実装を見ていきます!

case R.id.clear:
    if (calc.getText().toString().endsWith("+") ||
        calc.getText().toString().endsWith("-") ||
        calc.getText().toString().endsWith("*") ||
        calc.getText().toString().endsWith("/") ) {
        
        // 演算記号を消す場合
        calcList.remove(calcList.size() -1 );
        tmpCalcNum = "";

    } else {

        // 演算記号以外を消す場合
        tmpCalcNum = tmpCalcNum.substring(0,tmpCalcNum.length() - 1);

    }

    // 表示文字列の最後の文字を削除する
    viewNum = calc.getText().toString().substring(0,calc.getText().toString().length()-1);
    calc.setText(viewNum);

    break;

演算記号を削除する場合、計算用に作っているcalcListの最後の要素にはこの演算記号が入っています。

演算記号が入っている要素をList#removeを使って削除します。
List#removeの引数には削除する要素を番号で指定します。
最初の要素は0、最後の要素はリストサイズ -1 になるので、今回はcalcList.size() - 1ですね。

演算記号以外を削除する場合は、tmpCalcNumの末尾を削除します。
tmpCalcNumには直近の演算項が入っています。(詳細は計算処理実装編)

2. CAボタンの実装

CAはすべて初期化する処理とするため、そこまで複雑ではないですね!

case R.id.clearall:
    // 表示文字の初期化
    calc.setText("");
    // 演算モードの初期化
    calcMode = "";
    // 計算用リストの初期化
    calcList.clear();
    // 直近の演算項を初期化
    tmpCalcNum = "";
    break;

処理に出てくる変数を順々に初期化しています。

3. 演算ボタンの修正

以下のような流れでボタンが押されたことを考慮して、
演算ボタンを少しだけ直しておきます。

  1. 「10+6+」の状態でCボタンが押される
    • tmpCalcNumには""が設定されている
  2. 「10+6」の状態で-ボタンが押される
    • tmpCalcNumには""が設定されたまま、calcListにaddされてしまう(←想定外の動き)

なので、各演算ボタンに1つだけ分岐を設けます。

case R.id.plus:
    if (!tmpCalcNum.equals("")) {
        calcList.add(tmpCalcNum);
    }
    calcList.add("+");

    viewNum = calc.getText().toString() + "+";
    calc.setText(viewNum);

    tmpCalcNum = "";

    break;

tmpCalcNumが""である場合は、calcListへのaddを行いません。

4. 動作確認

画像では伝わりにくいですが動かしてみます!
f:id:mtnanao:20200224185745p:plain

この状態でCボタンを押すと、、、
f:id:mtnanao:20200224185756p:plain
末尾の数字が消えました!

次にCAボタンを押してみます。
f:id:mtnanao:20200224185805p:plain
すべて削除されました!

Cボタン、CAボタンを押した後の計算結果も問題なかったです。


それでは今回はここまでです!
お疲れさまでした!!

電卓を作ろう【計算処理実装編】

今回は計算処理の実装です!
Listやfor文を駆使して実現させます!

やっとここまで来ました!
それではやっていきます。

1. 数字・小数点ボタン処理実装

まずは数字と小数点のボタン処理にコードを追加していきます。
例として"1"が押された時のコードを載せておきます。

// 1が押された場合の処理
case R.id.one:

    viewNum = calc.getText().toString() + "1";
    calc.setText(viewNum);

    tmpCalcNum += "1";

    break;

追加したのは以下の1行です。

tmpCalcNum += "1";

変数tmpCalcNumは文字列型で宣言してあり、直前の演算記号以降に押された数字を保持します。
例えば 「10+5+30」 の場合は、
変数tmpCalcNumには"30"が入っていることになります。

2. 演算記号ボタン処理実装

次に演算記号が押された場合の処理です。
例として"+"が押された場合の処理が以下です。

// +が押された場合の処理
case R.id.plus:

    // calcListに計算する情報を追加する。(数字と演算記号)
    calcList.add(tmpCalcNum);
    calcList.add("+");
    tmpCalcNum = "";

    viewNum = calc.getText().toString() + "+";
    calc.setText(viewNum);

    break;

calcListは文字列型のリストで宣言しています。
このリストにList#addを使い、変数tmpCalcNumと文字列"+"を追加します。
先ほどの例をもう一度使うと、
 「10+5+30」
この状態で"+"を押すと、"30"と"+"がcalcListに追加されるというわけです。
そして演算記号が押されたことによりtmpCalcNumは初期化する必要があるため、空文字を設定します。
残りの"-"、"*"、"/"のボタンも同じように実装します。

3. "="ボタン処理実装

最後は、"="を押した時です。
このタイミングでcalcListに入っている数字と演算記号を順々に読んで計算していきます。

// =が押された場合の処理
case R.id.eq:

    // 直前の数字をcalcListに追加する
    calcList.add(tmpCalcNum);

    for (String calc : calcList) {

        // 演算記号の場合は、計算モードを設定する
        if (calc.equals("+")) {
            calcMode = "pl";
        } else if (calc.equals("-")) {
            calcMode = "mi";
        } else if (calc.equals("*")) {
            calcMode = "mu";
        } else if (calc.equals("/")) {
            calcMode = "di";
        } else {
            // 演算記号以外(数字)の場合は、計算モードを元に計算する
            if (calcMode.equals("pl")) {
                resultNum += Double.parseDouble(calc);
            } else if (calcMode.equals("mi")) {
                resultNum -= Double.parseDouble(calc);
            } else if (calcMode.equals("mu")) {
                resultNum *= Double.parseDouble(calc);
            } else if (calcMode.equals("di")) {
                resultNum /= Double.parseDouble(calc);
            } else {
                // 計算モードがどれでもない場合は、最初の数字なのでresultNumに設定
                resultNum = Double.parseDouble(calc);
            }
        }
    }

    calc.setText(resultNum.toString());

    calcMode = "";
    tmpCalcNum = "";

    calcList.clear();
    tmpCalcNum = resultNum.toString();

    break;

calcListをfor文で回していきます。
要素が演算記号の場合は、計算モードを指定します。
要素が演算記号でない場合(つまり数字の場合)は、計算モードに基づき計算を行います。
順々に計算していき、全要素を読み込んだあとは結果をTextViewに表示します。
結果を使って続けて電卓を打つことがあるので、最後に必要な変数を初期化します。

4. 動作確認

それでは動かしてみます!
f:id:mtnanao:20200222220127p:plain
f:id:mtnanao:20200222220137p:plain

正しく計算されていますね!

(掛け算と割り算を最初に計算するように作られてないのは内緒。笑)
(あと整数しか入れてないのに結果が少数点表記なのは気になる・・・)


本日はここまでです!
お疲れ様でした!!

電卓を作ろう【表示処理実装編】

今回は各ボタンが押された時にTextViewに表示させる処理を実装していきます!

完成まで長そうです。笑
では、やっていきましょう!

1. イベントリスナーの追加

配置したすべてのボタンにイベントリスナーを追加していきます。
イベントリスナーについてはこちらも参考にどうぞ。
xprogrammingx.hatenablog.com

実装したonCreateメソッドがこちらです。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 2020.02.24 電卓の計算処理実装
    findViewById(R.id.one).setOnClickListener(this);
    findViewById(R.id.two).setOnClickListener(this);
    findViewById(R.id.three).setOnClickListener(this);
    findViewById(R.id.four).setOnClickListener(this);
    findViewById(R.id.five).setOnClickListener(this);
    findViewById(R.id.six).setOnClickListener(this);
    findViewById(R.id.seven).setOnClickListener(this);
    findViewById(R.id.eight).setOnClickListener(this);
    findViewById(R.id.nine).setOnClickListener(this);
    findViewById(R.id.zero).setOnClickListener(this);
    findViewById(R.id.period).setOnClickListener(this);
    findViewById(R.id.plus).setOnClickListener(this);
    findViewById(R.id.minus).setOnClickListener(this);
    findViewById(R.id.multi).setOnClickListener(this);
    findViewById(R.id.div).setOnClickListener(this);
    findViewById(R.id.eq).setOnClickListener(this);
    findViewById(R.id.clear).setOnClickListener(this);
    findViewById(R.id.clearall).setOnClickListener(this);

    calc = findViewById(R.id.calc);
}

ボタンが多いとこれだけで一苦労ですね。笑
足りてるよね・・・?

2. onClickメソッドの実装

onClickメソッドを追加し、switch文を追加。
過去に触れているのでここでの解説は省略します。
xprogrammingx.hatenablog.com


各ボタンが押された場合の処理を実装していきます。
処理の流れはこんな感じでしょうか!

  1. TextViewの文字列を取得
  2. 押された文字を末尾に追加
  3. 再度TextViewに表示

例として、"1"が押された場合の処理がこちらです!

// 1が押された場合の処理
case R.id.one:
    viewNum = calc.getText().toString() + "1";
    calc.setText(viewNum);
    break;

これを各ボタンが押された場合の処理にも追加していきます。

3. 動作確認

それでは、正しく表示されるか確認してみます!
f:id:mtnanao:20200222203721p:plain

各数字と演算記号が表示されてますね!




それでは、今回はここまでとします!
次回はいよいよ電卓のメイン、計算処理です!

お疲れさまでした!