Android Open Source - Tip_Calculator Activity Main






From Project

Back to project page Tip_Calculator.

License

The source code is released under:

Apache License

If you think the Android project Tip_Calculator listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.collinguarino.tipcalculator;
/*from  w  w  w. ja  v  a 2  s  .  c om*/
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.os.Bundle;
import android.text.Editable;
import android.text.Selection;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;


public class ActivityMain extends Activity {

    // UI elements
    CleanEditText billInput, tipPercentInput, splitInput, taxInput;
    SeekBar tipPercentSeekBar, splitSeekBar;
    ImageButton subTipPercent, addTipPercent, subSplit, addSplit;
    TextView tipAmountText, totalAmountText;
    LinearLayout rootView, taxLayout;

    // other
    InputMethodManager keyboard;
    SharedPreferences preferences;
    SharedPreferences.Editor preferenceEditor;
    List<CleanEditText> editTexts;

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

        billInput = (CleanEditText) findViewById(R.id.billInput);
        tipPercentInput = (CleanEditText) findViewById(R.id.tipPercentInput);
        splitInput = (CleanEditText) findViewById(R.id.splitInput);
        taxInput = (CleanEditText) findViewById(R.id.taxInput);
        tipPercentSeekBar = (SeekBar) findViewById(R.id.tipPercentSeekBar);
        splitSeekBar = (SeekBar) findViewById(R.id.splitSeekBar);
        subTipPercent = (ImageButton) findViewById(R.id.sub_tip);
        addTipPercent = (ImageButton) findViewById(R.id.add_tip);
        subSplit = (ImageButton) findViewById(R.id.sub_split);
        addSplit = (ImageButton) findViewById(R.id.add_split);
        tipAmountText = (TextView) findViewById(R.id.tipAmountText);
        totalAmountText = (TextView) findViewById(R.id.totalAmountText);
        rootView = (LinearLayout) findViewById(R.id.rootView);
        taxLayout = (LinearLayout) findViewById(R.id.taxLayout);

        preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        preferenceEditor = preferences.edit();
        keyboard = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

        editTexts = new ArrayList<CleanEditText>();
        editTexts.add(billInput);
        editTexts.add(tipPercentInput);
        editTexts.add(splitInput);
        editTexts.add(taxInput);
        final List<CleanEditText> editTextList = new ArrayList<CleanEditText>(editTexts);
        for (final CleanEditText editText : editTextList) {
            editText.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    v.onTouchEvent(event);
                    editText.setCursorVisible(true);
                    return true;
                }
            });
        }

        // setup default preferences and variables
        setupDefaults();

        // start with bill input edittext in focus and open keyboard for fast entry
        billInput.requestFocus();
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

        /**
         * onImeBack is a keyboard close listener.
         * When the keyboard is closed, hide the cursor and remove the focus.
         */
        billInput.setOnEditTextImeBackListener(new CleanEditText.EditTextImeBackListener() {
            @Override
            public void onImeBack(CleanEditText ctrl, String text) {
                billInput.setCursorVisible(false);
                billInput.clearComposingText(); // fixes underline bug
                billInput.setText(billInput.getText().toString());
            }
        });

        // percent input edittext (same trick as bill input)
        tipPercentInput.setOnEditTextImeBackListener(new CleanEditText.EditTextImeBackListener() {
            @Override
            public void onImeBack(CleanEditText ctrl, String text) {
                tipPercentInput.setCursorVisible(false);
                rootView.requestFocus();

                if (tipPercentInput.getText().length() == 0) {
                    tipPercentInput.setText("0");
                }
            }
        });

        // split edittext (same trick as bill input)
        splitInput.setOnEditTextImeBackListener(new CleanEditText.EditTextImeBackListener() {
            @Override
            public void onImeBack(CleanEditText ctrl, String text) {
                splitInput.setCursorVisible(false);
                rootView.requestFocus();

                if (splitInput.getText().length() == 0) {
                    splitInput.setText("1");
                }
            }
        });

        // tax input edittext (same trick as bill input)
        taxInput.setOnEditTextImeBackListener(new CleanEditText.EditTextImeBackListener() {
            @Override
            public void onImeBack(CleanEditText ctrl, String text) {
                taxInput.setCursorVisible(false);
                rootView.requestFocus();
            }
        });

        billInput.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
                // resetting bill amount
                if (billInput.length() == 0) {
                    tipAmountText.setText("0.00");
                    totalAmountText.setText("0.00");
                }
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                calculateTip();
            }
        });

        tipPercentInput.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                // allow input of new max for seekbar
                if (tipPercentInput.length() > 0) {
                    if ((Integer.parseInt(tipPercentInput.getText().toString())) > tipPercentSeekBar.getMax()) {
                        tipPercentSeekBar.setMax((Integer.parseInt(tipPercentInput.getText().toString())));
                    }

                    if (tipPercentInput.length() >= 1) {
                        tipPercentSeekBar.setProgress(Integer.parseInt(tipPercentInput.getText().toString()));
                        calculateTip();
                    }

                    Editable etext = (Editable) tipPercentInput.getText();
                    Selection.setSelection(etext, etext.length());
                } else {
                    tipAmountText.setText("0.00");
                }
            }
        });

        taxInput.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                calculateTip();
            }
        });

        splitInput.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                if (splitInput.length() > 0) {
                    if ((Integer.parseInt(splitInput.getText().toString())) > splitSeekBar.getMax()) {
                        splitSeekBar.setMax((Integer.parseInt(splitInput.getText().toString())));
                    }

                    if (splitInput.length() >= 1) {
                        splitSeekBar.setProgress(Integer.parseInt(splitInput.getText().toString()));
                        calculateTip();
                    }

                    Editable etext = (Editable) splitInput.getText();
                    Selection.setSelection(etext, etext.length());
                }
            }
        });

        addTipPercent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // sync seekbar and textview values
                tipPercentSeekBar.setProgress(tipPercentSeekBar.getProgress() + 1);
                tipPercentInput.setText(String.valueOf(tipPercentSeekBar.getProgress()));

                hideKeyboard();
                hideCursor();
                calculateTip();
            }
        });

        addSplit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // sync seekbar and textview values
                splitSeekBar.setProgress(splitSeekBar.getProgress() + 1);
                splitInput.setText(String.valueOf(splitSeekBar.getProgress()));

                hideKeyboard();
                hideCursor();
                calculateTip();
            }
        });

        subTipPercent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // sync seekbar and textview values
                tipPercentSeekBar.setProgress(tipPercentSeekBar.getProgress() - 1);
                tipPercentInput.setText(String.valueOf(tipPercentSeekBar.getProgress()));

                hideKeyboard();
                hideCursor();
                calculateTip();
            }
        });

        subSplit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // sync seekbar and textview values
                splitSeekBar.setProgress(splitSeekBar.getProgress() - 1);
                splitInput.setText(String.valueOf(splitSeekBar.getProgress()));

                // split cannot go below 1 (avoid divide by zero error)
                if (splitSeekBar.getProgress() == 0) {
                    splitSeekBar.setProgress(1);
                }

                hideKeyboard();
                hideCursor();
                calculateTip();
            }
        });

        tipPercentSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                int tipSeekPercent = seekBar.getProgress();
                tipPercentInput.setText(String.valueOf(tipSeekPercent));

                calculateTip();
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                hideKeyboard();
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        splitSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                // split cannot go below 1 (avoid divide by zero error)
                if (splitSeekBar.getProgress() == 0)
                    splitSeekBar.setProgress(1);

                int splitAmount = seekBar.getProgress();
                splitInput.setText(String.valueOf(splitAmount));

                calculateTip();
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                hideKeyboard();
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

    }

    @Override
    protected void onResume() {
        super.onResume();
        setupDefaults();
    }

    /**
     * Called onStart and onResume
     * - Sets last tip percent as default
     * - Sets up tax section hide/show
     */
    private void setupDefaults() {
        // set as last tip percent
        int defaultTip = preferences.getInt("setLastDefaultTip", 20);
        tipPercentInput.setText(String.valueOf(defaultTip));
        tipPercentSeekBar.setProgress(defaultTip);

        // handle tax section preferences (hide/show)
        boolean taxSection = preferences.getBoolean("taxSectionShown", true);
        if (taxSection)
            taxLayout.setVisibility(View.VISIBLE);
        else
            taxLayout.setVisibility(View.GONE);
    }

    @Override
    protected void onPause() {
        super.onPause();
        preferenceEditor.putInt("setLastDefaultTip", Integer.parseInt(tipPercentInput.getText().toString()));
        preferenceEditor.commit();
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    }

    /**
     * Hides the cursor when focus is lost on edittexts
     */
    private void hideCursor() {
        billInput.setCursorVisible(false);
        tipPercentInput.setCursorVisible(false);
        splitInput.setCursorVisible(false);
        taxInput.setCursorVisible(false);
        rootView.requestFocus();
    }

    /**
     * Called every time a value is changed relating to text input to provide dynamic
     * real time calculations without having to hit a "done" button.
     */
    public void calculateTip() {

        // prevent decimal point crash as first char
        if (billInput.getText().toString().startsWith(".")) {
            billInput.setText("0.");

            int length = billInput.getEditableText().toString().trim().length();
            if (length > 1)
                billInput.setSelection(length);
        }

        // prevent decimal point crash as first char
        if (taxInput.getText().toString().startsWith(".")) {
            taxInput.setText("0.");

            int length = taxInput.getEditableText().toString().trim().length();
            if (length > 1)
                taxInput.setSelection(length);
        }

        if (billInput.length() > 0) {

            double tipPercent = tipPercentSeekBar.getProgress();
            double billAmountInt = Double.parseDouble(billInput.getText().toString());

            double taxAmount = 0.00;
            if (taxInput.getVisibility() == View.VISIBLE && taxInput.getText().toString().length() > 0)
                taxAmount = Double.parseDouble(taxInput.getText().toString());

            double totalTipInt = 0.00;
            if (!preferences.getBoolean("postTax", false))
                totalTipInt = ((tipPercent /100) * billAmountInt);
            else
                totalTipInt = ((tipPercent /100) * (billAmountInt + taxAmount));

            tipAmountText.setText(new DecimalFormat("0.00").format(totalTipInt));
            totalAmountText.setText(new DecimalFormat("0.00").format((billAmountInt + totalTipInt + taxAmount) / (splitSeekBar.getProgress())));
        }
    }

    /**
     * Used by many of the UI elements to hide the keyboard when an item is clicked.
     * This makes the tipping process much faster on the user end because the keyboard
     * is out of the way when it's not being used and they move onto the next step.
     */
    private void hideKeyboard() {
        keyboard.hideSoftInputFromWindow(tipPercentSeekBar.getWindowToken(), 0);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()) {
            case R.id.share:
                buildShareMessage();
                return true;
            case R.id.settings:
                startActivity(new Intent(this, ActivityPreferences.class));
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * Called by menu bar "share" button.
     * Constructs a sharing output based on values entered.
     */
    private void buildShareMessage() {

        // get output variables
        double billAmountInt = 0.00;
        if (billInput.getText().length() == 0) {
            billInput.setText("0.00");
        } else {
            billAmountInt = Double.parseDouble(billInput.getText().toString());
        }
        int tipPercent = tipPercentSeekBar.getProgress();
        double totalTipInt = (((tipPercent / 100) * billAmountInt) / splitSeekBar.getProgress());

        // build string based on above vars
        String totalShareOutput = "";
        if (billInput.getText().length() > 0) {
            // 2+ person split
            if (splitSeekBar.getProgress() > 1) {
                totalShareOutput = "Our bill is " + String.valueOf(
                    new DecimalFormat("0.00").format(Double.parseDouble(billInput.getText().toString()))) + "." + "\n" +
                    "We tipped at " + String.valueOf(tipPercentSeekBar.getProgress()) + "%." + "\n" +
                    "The bill is being split " + String.valueOf(splitSeekBar.getProgress()) + " ways." + "\n" +
                    "We each tip " + new DecimalFormat("0.00").format(totalTipInt) + "." + "\n" +
                    "We each pay " + totalAmountText.getText().toString() + ".";
            }
            // 1 person non split
            if (splitSeekBar.getProgress() <= 1) {
                totalShareOutput = "My bill is " + String.valueOf(
                    new DecimalFormat("0.00").format(Double.parseDouble(billInput.getText().toString()))) + "." + "\n" +
                    "I tipped at " + String.valueOf(tipPercentSeekBar.getProgress()) + "%." + "\n" +
                    "The total tip is " + tipAmountText.getText().toString() + "." + "\n" +
                    "I paid a total of " + totalAmountText.getText().toString() + ".";
            }

            Intent sharingIntent = new Intent(Intent.ACTION_SEND);
            sharingIntent.setType("text/plain");
            sharingIntent.putExtra(Intent.EXTRA_TEXT, totalShareOutput);
            startActivity(Intent.createChooser(sharingIntent, "Share Bill Using:"));
        }
    }
}




Java Source Code List

com.collinguarino.tipcalculator.ActivityMain.java
com.collinguarino.tipcalculator.ActivityPreferences.java
com.collinguarino.tipcalculator.ApplicationTest.java
com.collinguarino.tipcalculator.CleanEditText.java
com.collinguarino.tipcalculator.TipCalculatorDashClock.java
com.collinguarino.tipcalculator.WidgetProvider.java