Skip to content

Instantly share code, notes, and snippets.

@tahb
Created July 29, 2013 13:23
Show Gist options
  • Save tahb/6104271 to your computer and use it in GitHub Desktop.
Save tahb/6104271 to your computer and use it in GitHub Desktop.
Example logic for tipping application
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