Created
July 29, 2013 13:23
-
-
Save tahb/6104271 to your computer and use it in GitHub Desktop.
Example logic for tipping application
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.tippers; | |
import java.math.BigDecimal; | |
import java.text.NumberFormat; | |
import android.os.Bundle; | |
import android.app.Activity; | |
import android.content.SharedPreferences; | |
import android.view.Menu; | |
import android.view.View; | |
import android.widget.Button; | |
import android.widget.CheckBox; | |
import android.widget.SeekBar; | |
import android.widget.SeekBar.OnSeekBarChangeListener; | |
import android.widget.TextView; | |
import android.widget.Toast; | |
public class MainActivity extends Activity implements OnSeekBarChangeListener { | |
public static final String PREFS_NAME = "MyPrefsFile"; | |
private TextView percentage_amount; | |
private SeekBar percentage_value; | |
private TextView people_amount; | |
private SeekBar people_value; | |
private TextView bill_amount; | |
private TextView your_tip; | |
private TextView total_bill_value; | |
private TextView per_person; | |
private Button percentage_minus; | |
private Button percentage_plus; | |
private Button people_minus; | |
private Button people_plus; | |
private CheckBox cash_checkbox; | |
private SharedPreferences preferences; | |
private static final int max_people = 24; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
// Load preferences | |
preferences = getSharedPreferences(PREFS_NAME, 0); | |
// Set variables as application references | |
percentage_amount = (TextView) findViewById(R.id.percentage_value); | |
percentage_value = (SeekBar) findViewById(R.id.percentage_seekbar); | |
people_amount = (TextView) findViewById(R.id.people_value); | |
people_value = (SeekBar) findViewById(R.id.people_seekbar); | |
bill_amount = (TextView) findViewById(R.id.bill_amount); | |
your_tip = (TextView) findViewById(R.id.your_tip_value); | |
total_bill_value = (TextView) findViewById(R.id.total_bill_value); | |
per_person = (TextView) findViewById(R.id.per_person_value); | |
cash_checkbox = (CheckBox) findViewById(R.id.cash_checkbox); | |
people_plus = (Button) findViewById(R.id.people_plus); | |
people_minus = (Button) findViewById(R.id.people_minus); | |
percentage_plus = (Button) findViewById(R.id.percentage_plus); | |
percentage_minus = (Button) findViewById(R.id.percentage_minus); | |
// Set SeekBar Listeners and max values | |
percentage_value.setMax(100); | |
percentage_value.setProgress(Integer.parseInt(percentage_amount.getText().toString())); | |
percentage_value.setOnSeekBarChangeListener(this); | |
people_value.setMax(max_people); | |
people_value.setProgress(Integer.parseInt(people_amount.getText().toString())); | |
people_value.setOnSeekBarChangeListener(this); | |
// Listeners for plus and minus buttons | |
people_plus.setOnClickListener(new View.OnClickListener() { | |
public void onClick(View v) { | |
// When clicked get the current value and convert to integer | |
int old_amount = Integer.parseInt(people_amount.getText().toString()); | |
// Increment by 1 as this is the plus listener | |
int new_amount = old_amount + 1; | |
// Ensure the value stays within bounds | |
if (new_amount > max_people) { | |
new_amount = max_people; | |
} | |
// Update the amount text field with this new value | |
people_amount.setText(Integer.toString(new_amount)); | |
// Update the SeekBar to represent this new value | |
people_value.setProgress(new_amount); | |
} | |
}); | |
people_minus.setOnClickListener(new View.OnClickListener() { | |
public void onClick(View v) { | |
int old_amount = Integer.parseInt(people_amount.getText().toString()); | |
int new_amount = old_amount - 1; | |
if (new_amount < 1) { | |
new_amount = 1; | |
} | |
people_amount.setText(Integer.toString(new_amount)); | |
people_value.setProgress(new_amount); | |
} | |
}); | |
// Listeners for percentage plus and minus buttons, editing the values and SeekBar as appropriate | |
percentage_plus.setOnClickListener(new View.OnClickListener() { | |
public void onClick(View v) { | |
int old_amount = Integer.parseInt(percentage_amount.getText().toString()); | |
int new_amount = old_amount + 1; | |
if (new_amount > 100) { | |
new_amount = 100; | |
} | |
percentage_amount.setText(Integer.toString(new_amount)); | |
percentage_value.setProgress(new_amount); | |
} | |
}); | |
percentage_minus.setOnClickListener(new View.OnClickListener() { | |
public void onClick(View v) { | |
int old_amount = Integer.parseInt(percentage_amount.getText().toString()); | |
int new_amount = old_amount - 1; | |
if (new_amount <= 0) { | |
new_amount = 1; | |
} | |
percentage_amount.setText(Integer.toString(new_amount)); | |
percentage_value.setProgress(new_amount); | |
} | |
}); | |
} | |
@Override | |
public boolean onCreateOptionsMenu(Menu menu) { | |
// Inflate the menu; this adds items to the action bar if it is present | |
getMenuInflater().inflate(R.menu.activity_main, menu); | |
return true; | |
} | |
protected void onResume() { | |
super.onResume(); | |
// Access the shared preferences | |
preferences = getSharedPreferences(PREFS_NAME, 0); | |
// Find stored value | |
int percent = preferences.getInt("percent", 15); | |
// Update fields with these values or defaults | |
percentage_amount.setText(Integer.toString(percent)); | |
percentage_value.setProgress(percent); | |
} | |
@Override | |
protected void onPause() { | |
super.onPause(); | |
// Grab the current percent | |
int percent = Integer.parseInt(percentage_amount.getText().toString()); | |
// Access the shared preferences | |
SharedPreferences.Editor editor = preferences.edit(); | |
// Update preferences with newest value | |
editor.putInt("percent", percent); | |
// Commit this edit | |
editor.commit(); | |
} | |
// Method called from the XML 'Reset' and 'Calculate' buttons via onClick | |
public void onClick(View view) { | |
// Determine which button was pressed | |
switch(view.getId()) { | |
case R.id.calculate: | |
// Call the Calculation method with the boolean for if it's cash or not | |
calculation(view, (cash_checkbox.isChecked())); | |
return; | |
case R.id.reset: | |
// Call Reset method which planks out all the fields back to their default setting | |
reset(view); | |
return; | |
} | |
} | |
public void calculation(View view, boolean cash) { | |
int input_percentage = 0; | |
float input_bill = 0; | |
// Quick value access to check the values are valid | |
try { | |
input_percentage = Integer.parseInt(percentage_amount.getText().toString()); | |
} catch (NumberFormatException e) { | |
Toast toast = Toast.makeText(this, "Input Percent invalid", Toast.LENGTH_SHORT); | |
toast.show(); | |
} | |
try { | |
input_bill = Float.parseFloat(bill_amount.getText().toString()); | |
} catch (NumberFormatException e) { | |
Toast toast = Toast.makeText(this, "Input Bill invalid", Toast.LENGTH_SHORT); | |
toast.show(); | |
} | |
// Check the values sent for calculation fall within bounds | |
if (input_bill > 0.00) { | |
if (input_percentage > 0 && input_percentage <= 100) { | |
// Create BigDecimal variables | |
BigDecimal one_hundred = new BigDecimal("100"); | |
BigDecimal twenty = new BigDecimal("20"); | |
BigDecimal percentage = new BigDecimal(percentage_amount.getText().toString()); | |
BigDecimal bill = new BigDecimal(bill_amount.getText().toString()); | |
BigDecimal people = new BigDecimal(people_amount.getText().toString()); | |
BigDecimal individual_tip_output = null; | |
BigDecimal bill_divided = null; | |
// Find out the total tip for all people | |
BigDecimal tip = bill.divide(one_hundred, 2, 2); | |
tip = tip.multiply(percentage); | |
// Find out the tip for each person | |
individual_tip_output = tip.divide(people, 2, 2); | |
// Find out the how much of the bill each person has to pay | |
bill_divided = bill.divide(people, 2, 0); | |
// Calculate the exact per person cost (unrounded) | |
BigDecimal pp = individual_tip_output.add(bill_divided); | |
if (cash) { | |
BigDecimal xpp = null; | |
BigDecimal difference = null; | |
// 5p Rounding | |
if (pp.doubleValue() < 1.00) { | |
// Round this to nearest 0.05 | |
xpp = new BigDecimal(pp.multiply(twenty) | |
.add(new BigDecimal("0.5")) | |
.toBigInteger()).divide(twenty); | |
if (xpp == new BigDecimal("0.00")) { | |
xpp = new BigDecimal("0.05"); | |
} | |
if (xpp.doubleValue() > pp.doubleValue()) { | |
// Rounded up | |
difference = xpp.subtract(pp); | |
individual_tip_output = individual_tip_output.add(difference); | |
} else { | |
// Rounded down | |
// Tip can't be rounded down to exactly 0.00 | |
if (individual_tip_output.doubleValue() == 0.00) { | |
BigDecimal force_up = new BigDecimal("0.05"); | |
individual_tip_output = individual_tip_output.add(force_up); | |
xpp = xpp.add(force_up); | |
} | |
// If the rounding falls into negative range, force it to re-round up | |
if (individual_tip_output.doubleValue() < 0.00) { | |
xpp = pp.setScale(2, BigDecimal.ROUND_UP); | |
difference = xpp.subtract(pp); | |
individual_tip_output = individual_tip_output.add(difference); | |
} | |
} | |
pp = xpp; | |
} | |
// £1 Rounding | |
if (pp.doubleValue() > 1.00 && pp.doubleValue() < 100.00) { | |
xpp = pp.setScale(0, BigDecimal.ROUND_HALF_UP); | |
if (xpp.doubleValue() > pp.doubleValue()) { | |
// Rounded up | |
difference = xpp.subtract(pp); | |
individual_tip_output = individual_tip_output.add(difference); | |
} else { | |
// Rounded down | |
difference = pp.subtract(xpp); | |
individual_tip_output = individual_tip_output.subtract(difference); | |
// Tip can't be rounded to exactly 0.00 | |
if (individual_tip_output.doubleValue() == 0.00) { | |
BigDecimal force_up = new BigDecimal("0.05"); | |
individual_tip_output = individual_tip_output.add(force_up); | |
xpp = xpp.add(force_up); | |
} | |
// If the rounding falls into negative range, force it to re-round up | |
if (individual_tip_output.doubleValue() < 0.00) { | |
xpp = pp.setScale(0, BigDecimal.ROUND_UP); | |
difference = xpp.subtract(pp); | |
individual_tip_output = individual_tip_output.add(difference); | |
} | |
} | |
pp = xpp; | |
} | |
// £5 Rounding | |
if (pp.doubleValue() > 100.00 && pp.intValue() % 5 != 0) { | |
BigDecimal one = new BigDecimal("1"); | |
BigDecimal two = new BigDecimal("2"); | |
xpp = pp.setScale(0, BigDecimal.ROUND_HALF_UP); | |
double mod = (xpp.doubleValue() % 5); | |
if (mod == 1) { | |
// Round down | |
xpp = xpp.subtract(one); | |
individual_tip_output = individual_tip_output.subtract(one); | |
} else if (mod == 2) { | |
// Round down | |
xpp = xpp.subtract(two); | |
individual_tip_output = individual_tip_output.subtract(two); | |
} else if (mod == 3) { | |
// Round up | |
xpp = xpp.add(two); | |
individual_tip_output = individual_tip_output.add(two); | |
} else if (mod == 4) { | |
// Round up | |
xpp = xpp.add(one); | |
individual_tip_output = individual_tip_output.add(one); | |
} | |
pp = xpp; | |
} | |
} | |
// Add up the total tip and the total bill to find the total payable for everyone | |
BigDecimal total_bill = pp.multiply(people); | |
// Set these new values WITH LOCATION to determine correct currency to use | |
your_tip.setText(String.valueOf(NumberFormat.getCurrencyInstance().format(individual_tip_output))); | |
total_bill_value.setText(String.valueOf(NumberFormat.getCurrencyInstance().format(total_bill))); | |
per_person.setText(String.valueOf(NumberFormat.getCurrencyInstance().format(pp))); | |
} else { | |
// Handle error or do nothing | |
Toast toast = Toast.makeText(this, "Percentage to high or low", Toast.LENGTH_SHORT); | |
toast.show(); | |
} | |
} else { | |
// Handle error or do nothing | |
Toast toast = Toast.makeText(this, "Please enter a Bill above 0", Toast.LENGTH_SHORT); | |
toast.show(); | |
} | |
} | |
public void reset(View view) { | |
// Reset all values to blank and default, including preferences | |
bill_amount.setText(String.valueOf("")); | |
// Access the shared preferences if the app is being reopened from | |
preferences = getSharedPreferences(PREFS_NAME, 0); | |
int percent = preferences.getInt("percent", 15); | |
percentage_amount.setText(Integer.toString(percent)); | |
percentage_value.setProgress(percent); | |
// Default value set to 4 people | |
people_value.setProgress(4); | |
cash_checkbox.setChecked(false); | |
people_amount.setText("4"); | |
your_tip.setText("0.00"); | |
total_bill_value.setText("0.00"); | |
per_person.setText("0.00"); | |
Toast toast = Toast.makeText(this, "Reset Complete", Toast.LENGTH_SHORT); | |
toast.show(); | |
} | |
@Override | |
public void onProgressChanged(SeekBar arg0, int progress, boolean arg2) { | |
if (arg0.equals(percentage_value)) | |
{ | |
// Enforce percentage in bounds as range includes 0 | |
if (progress < 1) progress = 1; | |
// Set new value for percent | |
percentage_amount.setText(Integer.toString(progress)); | |
} | |
else if (arg0.equals(people_value)) | |
{ | |
// Enforce people in bounds as range includes 0 | |
if (progress < 1) progress = 1; | |
// Set new value for people | |
people_amount.setText(Integer.toString(progress)); | |
} | |
return; | |
} | |
@Override | |
public void onStartTrackingTouch(SeekBar arg0) { | |
// TODO Auto-generated method stub | |
} | |
@Override | |
public void onStopTrackingTouch(SeekBar arg0) { | |
// TODO Auto-generated method stub | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment