AndroidStudioで電卓できた②

スポンサーリンク
スポンサーリンク
スポンサーリンク

心変わり

昨日(一昨日になった)できあがったことで、満足しててきとーな記事になってしまった。

でもやっぱり、初めてちゃんとできあがったアプリだし

考えたこととか、分かんないこととか残しとこうと思う。

ソースはこっち。電卓の中身とかは書けるほど考えてない。

import

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

そもそもimportって…なに…?というレベルだったので

コードで「ここアカンぞ」って言われた時にAlt+Enterを

押すと勝手に追加されていった。べんり。

未だに何の為に追加されているのか分からないっていう。

viewとかwidgetとかついてるからこれら使うのに必要なんだろう。

変数の宣言

public class MainActivity extends AppCompatActivity {
    String opText;
    String outText;
    boolean afterOp;
    boolean isStacked;
    Float StackedValue;

変数を書く位置も分かってなかった。

最初onClickの中で宣言してたのだが、そうすると変数に値が保持されていない。

booleanはいつもfalseだし、StackedValueはいつも空。

ボタンを押すごとに突飛な数字が表示されるし、最悪落ちる。

あ、ここに書けばいいんだって分かった時は腑に落ちた感がすごかった。

Activity全体で使う変数はここに書けばいいんだね。

あと初期化してない、そういえば。でも動く。すごい。

ボタンにリスナを設定

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

        Button bt1Click = findViewById(R.id.button1);
        ButtonClick bt1listener = new ButtonClick();
        bt1Click.setOnClickListener(bt1listener);
//省略

ここが冗長な気がしてる。

画面の作り方をもっと調べれば、簡単に書けるんじゃないだろか。

ただ今はこれしか知らんので、こうやった。

あと@Overrideの意味が分からない…。もう全然分からない。

最初プロジェクトを新規作成した時にあったのでそのままにしてる。

いつか謎が解けるんだろうか。

ここがボタンのイベントハンドラなの?

private class ButtonClick implements View.OnClickListener{
    TextView output = findViewById(R.id.tvOutput);

これはもう、こう書けばTextViewを取得できるよっていうのをそのまま書いた。

ただ書く場所は果たしてここでよかったのか、動いてるからいいんだろうけど

確証があってこうしてるわけではないので、完全に手探り。

関数AppendTexts

void appendTexts(String t){
    outText = output.getText().toString();

    if (!afterOp && !(outText.equals("0"))) {
        t = outText + t;
    }else if(t.equals(".")) {
        t = "0" + t;
    }

    output.setText(t);
    afterOp = false;
}

参考にしたサイトから引っ張ってきている。

ただ、そのまま引っ張ってきたら、「0」の後に「1」を押すと「01」って

表示されちゃったので、!(outText.equals(“0”))で0を除外。

あと表示が「0」の時に「.」を押すと「.123」みたいになってしまったので

それ用に処理を入れた。

文字列の比較で「==」を使ったら

String values are compared using ‘==’, not ‘equals()’ less… (Ctrl+F1)
Reports any use of == or != to test for String equality, rather than the equals() method.

「equals」使えって怒られた。

あと多分全然分かってないのが関数の宣言方法ね。

↑になる以前はvoidの前にPublicって入ってた。

「java 関数 作り方」とかでググったサイトにそう載ってたからね。

でもPublicって入ってると

Access can be package-private less… (Ctrl+F1)
This inspection reports all fields, methods or classes, found in the specified inspection scope, that may have their access modifier narrowed down.

つってさ、怒られるの。多分スコープが適切じゃねえよ?つってるんだろうけど

じゃあどうすればいいの?ってさ、なるじゃない。スコープなんてまだ分かってないんだし。

で、とりあえず取ってみたら消えた。ので、一安心。

残る謎はvoidだ。これ一体なんの為に付いてるんだろう。

そういえば、これが初めて作った関数なんだなぁ。

VBAでも使ったことなかったりする。

同じような処理は同じコードをコピペして使いまわしてた。

それに比べればだいぶ進歩したなぁ。

関数Calculation

void Calculation(String o, Float s){
    Float r = 0.0f;

    if(o.equals("+")){
        r = s + Float.parseFloat(output.getText().toString());

    }else if(o.equals("-")){
        r = s - Float.parseFloat(output.getText().toString());

    }else if(o.equals("×")){
        r = s * Float.parseFloat(output.getText().toString());

    }else if(o.equals("÷")) {
        r = s / Float.parseFloat(output.getText().toString());
    }

    if(r == r.intValue() ){
        output.setText(String.valueOf(r.intValue()));
    }else{
        output.setText(r.toString());
    }
}

計算する関数~!

Float.parseFloat(output.getText().toString())で表示からText取得してStringに変換した後

Floatに型変換…のつもり。これもっと短く書けないのかな。

でもとりあえずやりたいことができてるんでいいかな。

引数はButtonの文字とTextViewの数字だったな確か。

引数2個のも作れた。最高やね。

1個目のifのところで

‘if’ statement replaceable with ‘switch’ statement less… (Ctrl+F1)
Reports any if statements with which can be replaced by a switch statement. This inspection will automatically suggest string switches when the project language level is Java 7 or higher.

Switch文も書けないの?ぷぷぷwって言われてるけど無視してる。

あ、あとAppendTextsのpublicも再び。

2個目のifは計算結果が整数値だったときに、「2.0」って小数部分を表示

させるんじゃなく、「2」って表示させたいがために入れてる。

output.setText(r.toString());のところで

Number formatting does not take into account locale settings. Consider using String.format instead. less… (Ctrl+F1)
When calling TextView#setText * Never call Number#toString() to format numbers; it will not handle fraction separators and locale-specific digits properly. Consider using String#format with proper format specifications (%d or %f) instead. * Do not pass a string literal (e.g. “Hello”) to display text. Hardcoded text can not be properly translated to other languages. Consider using Android resource strings instead. * Do not build messages by concatenating text chunks. Such messages can not be properly translated. Issue id: SetTextI18n More info: http://developer.android.com/guide/topics/resources/localization.html

て、怒られるんですけどよく分かんないんです。

String.format使えよって言われてるのかな。でも、この使い方でちゃんと

整形されるような引数が分からなかった。まぁ、動いてるので…。

今思ったんだけど

void Calculation(String o, Float s){
    Float r = 0.0f;
    Float t = Float.parseFloat(output.getText().toString());

    if(o.equals("+")){
        r = s + t;

    }else if(o.equals("-")){
        r = s - t;

    }else if(o.equals("×")){
        r = s * t;

    }else if(o.equals("÷")) {
        r = s / t;
    }

    if(r == r.intValue() ){
        output.setText(String.valueOf(r.intValue()));
    }else{
        output.setText(r.toString());
    }
}

とかのがかっこいいかな。好みか。

onClickメソッド

public void onClick(View view) {
    String apText;
    int id = view.getId();
    Button btn = (Button) view;

apTextってなんでここで宣言してるんだろう。なんとなく、かな。

view.getId();で押されたボタンのidを取ってきて、switchで振る方法を取ることに。

あとButtonのTextを取得したいのでviewからキャスト。全部受け売りです。

数字ボタン

switch(id){
    case R.id.button0:
    case R.id.button1:
    case R.id.button2:
    case R.id.button3:
    case R.id.button4:
    case R.id.button5:
    case R.id.button6:
    case R.id.button7:
    case R.id.button8:
    case R.id.button9:
        apText = btn.getText().toString();
        appendTexts(apText);
        break;

caseをもっときれいに書けないのかな。なんかありそうだけど。

forで回すとか?

btn.getText().toString();でButtonのTextを取得してappendTextsに渡してるだけ。

ButtonのTextを取得する方法を見つけるまでは

0~9までに同じようなコードが並んでたなぁ…

演算子ボタン(+-*/)

case R.id.buttonplus:
case R.id.buttonminus:
case R.id.buttonby:
case R.id.buttondiv:
    if(isStacked) {
        Calculation(opText, StackedValue);
    }

    StackedValue = Float.parseFloat(output.getText().toString());
    isStacked = true;
    afterOp = true;
    opText = btn.getText().toString();
    break;

ここで結構詰まった。

opTextに押された演算子を代入しておくわけだけど

最初case~if(isStacked)の間に書いていた。

そうすると例えば、10+30-20という計算をするとき「-」を押した際に

本来であれば40と表示されなければならないのだが-20と表示されてしまう。

StackedValueに10が入っていて、表示が30。この状態で「-」ボタンを押すと

10-30になってしまうというわけだ。

この時点では「=」を実装していなかった為か、どのタイミングでどの演算子を

使う、ということがきちんと理解して組み立てられていなかった。

結果、演算子代入のタイミングをCalculationメソッド呼び出しの後にすることで

事なきを得た。設計からやっていないとやっぱダメなんだなぁと思った。ちぇ。

演算子ボタン(=)

case R.id.buttonequal:
    if(isStacked){
        Calculation(opText,StackedValue);
    }

    isStacked = false;
    afterOp = true;
    break;

前記の事があったので、特に悩まず。

今ちょっと思ったのが、ここでisStackedをfalseにしとくのが正しいのか。

StackedValueの値を更新するべきなんじゃないかとか。

あとでtrueにした時、どんな事が起こるか試そっと。

ていうか本物の電卓と比べりゃいいのか。

「.」ボタン

case R.id.buttonperiod:
    String dplText;
    dplText = output.getText().toString();

    if (!dplText.contains(".")){
        appendTexts(".");
    }
    break;

表示文字列を取ってきて、「.」が含まれてなかったら「.」をつなげると。

.contains()っていうのを覚えました^^

Cボタン

case R.id.buttonc:
    output.setText("0");
    isStacked = false;
    afterOp = false;
    StackedValue = null;
    break;

変数とTextViewの表示を初期化してあげる。

なんとなくStackedValueをnullで初期化してしまってるんだけど

これでいいんだろうか。これじゃダメだった場合の理由を知りたいな。

0.0fとかの方がいいのかな。うむむ。

その他

演算子を連続で押したときの挙動が変かも。

例えば3+-+と押した時に3→3→6→0となる。

理由はわかるけど直し方が微妙だ。

 

0除算の処理もつけてない。

ただやってみたら表示が「Infinity」になったので

かっこいいと思ってそのままにした。

 

デバッグのやり方を覚えた。これが一番大きいかも。

VBAではF8を押すと1行ずつ処理が確認できて、把握しやすかった。

Androidでは実機で動かす以外のやり方を知らんかったので

把握しづらいなぁと思ってた。ちゃんと探すべきよね…。

 

こんな感じかな!

いかに自分が分かってないで作ってるかが分かっただけでも良し!

次はリバーシだ、1年ぐらいかなぁ~

スポンサーリンク
のーと
スポンサーリンク
スポンサーリンク
スポンサーリンク
dalomo

コメント

タイトルとURLをコピーしました