Back to project page Tip_Calculator.
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.
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:")); } } }