Format Price in 0.00 format in android using edittext - java

I am trying to mask a price value so that it is always in 0.00 format. Here is my code
float temp = 0;
DecimalFormat mDecimalFormat = new DecimalFormat("###.00");
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.toString()!=null)
{
mMasEditText.removeTextChangedListener(this);
temp = Float.parseFloat(s.toString());
mMasEditText.setText(""+mDecimalFormat.format(addNumber(temp)));
mMasEditText.setSelection(start+1);
mMasEditText.addTextChangedListener(this);
}
}
public float addNumber(float numTemp){
float result=0.00f;
result = numTemp + result;
return result;
}
But when I am pressing decimal, I want the cursor to go to one more step. But I am not able to get the dot callback. Also when I am pressing the back button, to remove digits, I get an index out of bound exception. Can anyone tell me how to get the back button and dot button callback before onTextChanged listener?

Recommended way of formatting currency and prices:
Locale loc = Locale.getDefault();
NumberFormat nf = NumberFormat.getCurrencyInstance(loc);
nf.setCurrency(Currency.getInstance(loc));
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
System.out.println(nf.format(23.5634));
System.out.println(nf.format(0.5));

use String.format
String.format("$%.2f", result);
or
Strint text = String.format("$%.2f", addNumber(temp));
mMasEditText.setText(text)

Related

Returning nothing instead of NaN

I'm creating a simple app that calculates BMI and I'm struggling with one small problem. I have 2 edit text fields, which are allowed to type numbers only. The point is when one of the text fields are empty the app is to generate a toast message and display nothing. I wrote an if statement to check if an edit text is empty and if not just to calculate further.
All would work fine, but I needed to put return statement and Android Studio suggested me writing "return 0;" so did I.
This is the code responsible for calculations:
/// parse input value from edittext field into double type
private double weight() {
EditText weightInput = (EditText) findViewById(R.id.weight_input);
String sWeightInput = weightInput.getEditableText().toString();
if (sWeightInput.matches("")){
Toast.makeText(this, R.string.noweight, Toast.LENGTH_SHORT).show();
} else {
String weight = sWeightInput;
double weightTyped = Double.parseDouble(weight);
return weightTyped;
}
return 0;
}
private double heigh() {
EditText heightInput = (EditText) findViewById(R.id.height_input);
String sHightInput = heightInput.getEditableText().toString();
if (sHightInput.matches("")){
Toast.makeText(this, R.string.noheight, Toast.LENGTH_SHORT).show();
} else {
String height = sHightInput;
double heightTyped = Double.parseDouble(height);
heightTyped = heightTyped / 100;
heightTyped = heightTyped * heightTyped;
return heightTyped;
}
return 0;
}
//make calculations and return the output value
public void makeCalculations(View view){
double result = weight() / heigh();
String message = String.valueOf(result);
TextView bmiSummaryTextView = (TextView) findViewById(R.id.bmi_calculation);
bmiSummaryTextView.setText(message);
}
This is the interface of the app.
To sum up, all I want to do is to display nothing instead of NaN (not a number).
Return a non-primitive Double rather than a double, and you will be able to use null as a value. Be sure to check for this value though, or you'll run into a NullPointerException.
Alternatively, you could look into using optionals, but since you're using Android you might need an external library for that (unless your minimum SDK version is high enough, then you can use Java 8's Optional).
The problem is probably if in your calculation weight() / height height is 0 it outputs NaN because it is infinity.
Also put your return 0; after Toast.makeText() in the condition. AS grumbles because you are not returning a value in the if branch.
if (sHightInput.matches("")){
Toast.makeText(this, R.string.noheight, Toast.LENGTH_SHORT).show();
return 0;
}
Maybe this will help you also to avoid dividing by zero.
public void makeCalculations(View view) {
String message = "Invalid input!";
if (weight() > 0 && height() > 0) {
double result = weight() / heigh();
String message = String.valueOf(result);
}
TextView bmiSummaryTextView = (TextView) findViewById(R.id.bmi_calculation);
bmiSummaryTextView.setText(message);
}

Decimal Format in Jframe?

I am making a pizza calculator but my results come out as "$7.5" instead of "$7.50". I have this decimal format code written out with my code below it, but it doesn't seem to work. Any ideas?
private void calculateButtonActionPerformed(java.awt.event.ActionEvent evt) {
double diameter;
double labourCost = 1.00;
diameter = Double.parseDouble(diameterInput.getText());
double storeCost = 1.50;
double materialsCost = 0.50 * diameter;
double totalCost = labourCost + storeCost + materialsCost;
DecimalFormat x = newDecimalFormat("0.00");
costOutput.setText("The cost of the pizza is $" + totalCost);
You're not using the result ("x") of the operation for anything. I'm guessing that replacing "totalCost" with "x" in the last line will help?
You need to use a Decimal Formatter to convert your floating point value over to a string.
// Make a new formatter with your format
DecimalFormat myFormatter = new DecimalFormat("$##.00");
// Convert your number to a human readable string
String output = myFormatter.format(22.99999f);
System.out.println(output); // Prints $23.00
See this page for details on the various patterns https://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html

Displaying Currency Format Issue

First post. I'm brand new to software development in general and have spent hours trying to figure this piece out. As you can see, I'm converting a double to a String, then assigning that value to textResult (String). I formatted it properly to display decimals, but I can't figure out how to show as currency instead.
Based on what i've found online, it looks like I may have to use
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
and then use nf.format() somehow but it just doesn't work for me. Any guidance would be greatly appreciated.
public void onCalculateDealOne(View v) {
//get values from text fields
EditText priceEntry = (EditText) findViewById(R.id.etListPriceDealOne);
EditText unitsEntry = (EditText) findViewById(R.id.etNumberOfUnitsDealOne);
EditText couponEntry = (EditText) findViewById(R.id.etCouponAmountDealOne);
//get value from result label
TextView result = (TextView) findViewById(R.id.perUnitCostDealOne);
//assign entered values to int variables
double price = Double.parseDouble(priceEntry.getText().toString());
double units = Double.parseDouble(unitsEntry.getText().toString());
double coupon = Double.parseDouble(couponEntry.getText().toString());
//create variable that holds the calculated result and then do the math
double calculatedResultDealOne = (price - coupon) / units;
//convert calculatedResult to string
String textResult = String.format("%.3f", calculatedResultDealOne);
result.setText(textResult + " per unit");
dealOneValue = calculatedResultDealOne;
//hide the keyboard
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
//make deal one label visible
result.setVisibility(View.VISIBLE);
}
There are two simple solutions to this. You can use a DecimalFormat object, or you can use a NumberFormat object.
I personally prefer a Decimalformat object because it gives you more precise control over how you would like to format your output value/text.
Some may prefer the NumberFormat object because the .getcurrencyInstance() method is easier to understand than a cryptic string format (e.g. "$#.00", "#0.00").
public static void main(String[] args) {
Double currency = 123.4;
DecimalFormat decF = new DecimalFormat("$#.00");
System.out.println(decF.format(currency));
Double numCurrency = 567.89;
NumberFormat numFor = NumberFormat.getCurrencyInstance();
System.out.println(numFor.format(numCurrency));
}
The output for this example program is below:
$123.40
$567.89
You need to use formatter to format the double value you want, eg:
double money = 202.2
NumberFormat formatter = NumberFormat.getCurrencyInstance();
String moneyString = formatter.format(money);
System.out.println(moneyString);

Why does dividing by zero result in 9.223372E+18?

I'm making an Android calculator and I get 9.223372E+18 when I divide by zero. why wouldn't it show NaN or crash? I think that it results in 9.223372E+18 because that's the largest possible double value, since I'm dividing by zero and using a double data type. Since it will confuse the user, how do I get around this?
Respond to Comments
Hi guys, thanks for all your responses. I appreciate it. I posted my code below.
public class CFM extends ActionBarActivity {
Double cfm, ac, volume;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cfm);
EditText e1 = (EditText) findViewById(R.id.editText1);
EditText e2 = (EditText) findViewById(R.id.editText2);
TextView t1 = (TextView) findViewById(R.id.editText3);
t1.setEnabled(false);
t1.setFocusable(false);
e1.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
EditText e1 = (EditText)findViewById(R.id.editText1);
EditText e2 = (EditText)findViewById(R.id.editText2);
volume = Double.parseDouble(e1.getText().toString());
cfm = Double.parseDouble(e2.getText().toString());
TextView t1 = (TextView) findViewById(R.id.editText3);
ac = cfm * 60 / volume;
t1.setText(Double.toString((double) Math.round(ac * 100) / 100));
}
});
e2.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
EditText e1 = (EditText)findViewById(R.id.editText1);
EditText e2 = (EditText)findViewById(R.id.editText2);
volume = Double.parseDouble(e1.getText().toString());
cfm = Double.parseDouble(e2.getText().toString());
TextView t1 = (TextView) findViewById(R.id.editText3);
ac = cfm * 60 / volume;
t1.setText(Double.toString((double) Math.round(ac * 100) / 100));
}
});
}
9223372036854775807 (roughly 9.223372E+18) is the largest possible long value. The only way I can see this coming from dividing by zero is if you have a variable of type long. For example, the following code prints 9223372036854775807.
long a = 1;
a /= 0.0;
System.out.println(a);
When you divide a long by a double, the long is converted to a double first and the result is a double. Any positive double divided by 0.0 gives Double.POSITIVE_INFINITY, so 1/0.0 is Double.POSITIVE_INFINITY. Since a has type long, this is converted back to a long, giving the largest possible long value.
However, we would need to see your code to understand why you have variables of type long.
Edit
Having seen your code, I now realise that the problem is not a variable of type long but your use of Math.round. This is defined as follows:
Returns the closest long to the argument, with ties rounding up.
Math.round therefore rounds Double.PositiveInfinity down to 9223372036854775807. A better approach to displaying the result to 2 decimal places would be something like this.
String result = Double.isInfinite(ac) || Double.isNaN(ac) ? "Error"
: new BigDecimal(ac).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
t1.setText(result);
This will print "Error" if the user tries to divide by zero.
When calculating your value, use a detection mechanism to look for that number and show an error of 'cannot divide by zero'.
Either that or see if there is an exception handler that handles division by zero. Check here for an example of what exception to throw:
How should I throw a divide by zero exception in Java without actually dividing by zero?
or here: Java division by zero doesnt throw an ArithmeticException - why?
OR as deyur mentioned, yes you can always check if one of the arguments is zero and handle it that way.
If you are still having issues beyond this, share the core code snippets so we can help.

Filter Input in Real-Time?

I have an EditText (accepts 0-9) with a listener. I want to grab input as it's entered, apply a calculation, and display it in the same EditText box.
The box initially displays $0.00. When the user inputs a 2, I want to grab that from the box, parse it to remove the $ and decimal, convert it to an int... divide it by 100 and put a $ in front of it. After setText, it should display $0.02. If they then press 5, I'll grab it, parse it, end up with 25, do the math and it should display $0.25, etc.
I don't know if this is the best way, I'm open to new ideas. Here is my current code:
mEditPrice.addTextChangedListener(new TextWatcher(){
DecimalFormat dec = new DecimalFormat("0.00");
#Override
public void afterTextChanged(Editable arg0) {
}
#Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
String userInput = mEditPrice.getText().toString().replaceAll("[^\\d]", "");
int userInputInt = Integer.parseInt(userInput);
mEditPrice.setText("$"+dec.format(userInputInt / 100));
}
There's a few issues to deal with here before you can achieve the kind of functionality you desire.
Whenever you deal with a TextWatcher you need to be careful when setting the text of the EditText object being watched. The reason for this is that every time you call setText on it, it will trigger the watcher again, causing your code to go into an infinite loop.
To prevent this, you should set the value of text you want to set into a variable outside of the onTextChanged method. When entering the method, check against this variable and only perform your processing code if the value is different from the CharSequence.
The integer variable userInputInt, when divided by 100, will be equal to zero.
This should be changed to a double to produce values like 0.02 etc.
After those changes we can get the EditText to show $0.02 after entering a 2. But because we have set the value of the EditText in code, the next entry into the EditText will be added to the beginning of the text. Then if we enter a '5' we get $50.02.
To overcome this, the last thing we need to do is set the position of the EditText to the end of the string, using the set position method.
Here's the final solution:
private String value;
mEditPrice.addTextChangedListener(new TextWatcher(){
DecimalFormat dec = new DecimalFormat("0.00");
#Override
public void afterTextChanged(Editable arg0) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!s.toString().equals(value)){
String userInput = mEditPrice.getText().toString().replaceAll("[^\\d]", "");
double userInputDouble = Double.parseDouble(userInput);
value = ("$"+dec.format(userInputDouble / 100));
mEditPrice.setText(value);
mEditPrice.setSelection(value.length());
}
}
});

Categories