【Android】 簡易電卓を作成する [2] ~実装編~

初めに

 * 以下の関連記事の続き。
http://blogs.yahoo.co.jp/dk521123/35248307.html

サンプル

MainActivity.java

import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipboardManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.math.BigDecimal;
import java.text.DecimalFormat;

public class MainActivity extends AppCompatActivity {
    private static final String ZERO = "0";
    private static final String DECIMAL = ".";
    private static final String FORMAT = "#,##0";
    private static final int INITIAL_FOR_ID = -1;
    private DecimalFormat format;
    private String inputTemporaryData = "";
    private String resultData = "";
    private int operatorId = INITIAL_FOR_ID;

    public MainActivity() {
        this.format = new DecimalFormat(FORMAT);
    }

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

    @Override
    public void onStop() {
        super.onStop();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public void numberOrDecimalKeyOnClick(View view) {
        Button button = (Button)view;
        String inputKeyText = (String) button.getText();

        if (!DECIMAL.equals(inputKeyText)) {
            this.inputTemporaryData = this.inputTemporaryData + inputKeyText;
        } else {
            if (this.inputTemporaryData.length() == 0) {
                this.inputTemporaryData = ZERO + DECIMAL;
            } else if (this.inputTemporaryData.indexOf(DECIMAL) == -1) {
                this.inputTemporaryData = this.inputTemporaryData + DECIMAL;
            }
        }

        this.showNumber(this.inputTemporaryData);
    }

    public void functionKeyOnClick(View view) {
        switch (view.getId()) {
            case R.id.allClearButton:
                this.inputTemporaryData = "";
                this.resultData = "";
                this.getSubTextView().setText("");
                break;
            case R.id.copyButton:
                this.copyOnClipboard(this.getDisplayTextView().getText().toString());
                break;
            case R.id.backSpaceButton:
                if (this.inputTemporaryData.length() != 0) {
                    this.inputTemporaryData =
                            this.inputTemporaryData.substring(0, this.inputTemporaryData.length() - 1);
                }
                break;
        }

        this.showNumber(this.inputTemporaryData);
    }

    public void operatorKeyOnClick(View view) {
        TextView subTextView = this.getSubTextView();

        int viewId = view.getId();
        Button currentOperatorButton = (Button)super.findViewById(viewId);
        String currentOperator = currentOperatorButton.getText().toString();
        if (this.operatorId != INITIAL_FOR_ID) {
            if (this.inputTemporaryData.length() > 0) {
                Button previousOperatorButton = (Button)super.findViewById(this.operatorId);
                String previousOperator = previousOperatorButton.getText().toString();
                subTextView.setText(this.resultData + previousOperator +
                                this.inputTemporaryData + currentOperator);
                this.resultData = this.getCalculationResult();
                this.showNumber(this.resultData);
            } else {
                subTextView.setText(this.resultData + currentOperator);
            }
        } else {
            if (this.inputTemporaryData.length() > 0) {
                this.resultData = this.inputTemporaryData;
            }
            subTextView.setText(this.resultData + currentOperator);
        }

        // Reset Parameters
        this.inputTemporaryData = "";
        if (viewId == R.id.equalButton) {
            this.operatorId = INITIAL_FOR_ID;
        } else {
            this.operatorId = viewId;
        }
    }

    private String getCalculationResult() {
        BigDecimal result = new BigDecimal(this.resultData);
        BigDecimal temporary = new BigDecimal(this.inputTemporaryData);
        BigDecimal returnValue = BigDecimal.ZERO;
        switch (this.operatorId) {
            case R.id.addButton:
                // +
                returnValue = result.add(temporary);
                break;
            case R.id.subtractButton:
                // -
                returnValue = result.subtract(temporary);
                break;
            case R.id.multiplyButton:
                // *
                returnValue = result.multiply(temporary);
                break;
            case R.id.divideButton:
                // /
                if (!BigDecimal.ZERO.equals(temporary)) {
                    returnValue = result.divide(temporary);
                } else {
                    Toast toast =Toast.makeText(
                            this, R.string.error_divide_by_zero, Toast.LENGTH_SHORT);
                    toast.show();
                }
                break;

        }
        if (returnValue.toString().indexOf(DECIMAL) >= 0) {
            return returnValue.toString().replaceAll("\\.0+$|0+$", "");
        } else {
            return returnValue.toString();
        }

    }

    private void showNumber(String number) {
        String shownNumber;
        if (number.length() > 0) {
            int decimalPointIndex = number.indexOf(DECIMAL);
            if (decimalPointIndex > -1) {
                String decimalNumber = number.substring(decimalPointIndex);
                String integerPart = number.substring(0, decimalPointIndex);
                shownNumber = this.format.format(Double.parseDouble(integerPart)) + decimalNumber;
            } else {
                shownNumber = this.format.format(Double.parseDouble(number));
            }
        } else {
            shownNumber = ZERO;
        }

        this.getDisplayTextView().setText(shownNumber);
    }

    private void copyOnClipboard(String copiedText) {
        String[] mimeTypes = new String[1];
        mimeTypes[0] = ClipDescription.MIMETYPE_TEXT_URILIST;
        ClipData.Item clipDataItem = new ClipData.Item(copiedText);

        ClipData clipData = new ClipData(new ClipDescription(copiedText, mimeTypes), clipDataItem);

        ClipboardManager clipboardManager =
                (ClipboardManager)super.getSystemService(CLIPBOARD_SERVICE);
        clipboardManager.setPrimaryClip(clipData);
    }

    private TextView getDisplayTextView() {
        return  (TextView)super.findViewById(R.id.displayTextView);
    }

    private TextView getSubTextView() {
        return  (TextView)super.findViewById(R.id.subTextView);
    }
}

strings.xml

<resources>
    <string name="app_name">SampleCalculator</string>

    <string name="error_divide_by_zero">You cannot divide by Zero...</string>
    <string name="action_settings">Settings</string>
</resources>