Format EditText to currency with whole numbers - java

All-
I have a TextWatcher that formats an EditText to currency format:
private String current = "";
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(!s.toString().equals(current)){
editText$.removeTextChangedListener(this);
String cleanString = s.toString().replaceAll("[$,.]", "");
double parsed = Double.parseDouble(cleanString);
String formated = NumberFormat.getCurrencyInstance().format((parsed/100));
current = formated;
editText$.setText(formated);
editText$.setSelection(formated.length());
editText$.addTextChangedListener(this);
}
}
This works great, the problem is that my EditText only needs whole numbers so I do not the user to be able to enter cents. So instead of 0.01 than 0.12 than 1.23 than 12.34, I want 1 than 12 than 123 than 1,234. How can I get rid of the decimal point but keep the commas? Thank you.

If you don't mind removing the period and trailing zeroes, you could do this:
mEditText.addTextChangedListener(new TextWatcher() {
private String current = "";
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!s.toString().equals(current)) {
annualIncomeEntry.removeTextChangedListener(this);
String cleanString = s.toString().replaceAll("[$,]", "");
if (cleanString.length() > 0) {
double parsed = Double.parseDouble(cleanString);
NumberFormat formatter = NumberFormat.getCurrencyInstance();
formatter.setMaximumFractionDigits(0);
current = formatter.format(parsed);
} else {
current = cleanString;
}
annualIncomeEntry.setText(current);
annualIncomeEntry.setSelection(current.length());
annualIncomeEntry.addTextChangedListener(this);
}
}
#Override
public void afterTextChanged(Editable s) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
});
This will set the number formatter's maximum fraction digits to zero, removing all trailing zeroes and the period. I also removed the division by 100 so that all entered numbers are integers.
Also make sure that your EditText's inputType is "number" or this will crash if the user tries to enter a non-numeric character.

Hexar's answer was useful but it lacked error detection when the user deleted all the numbers or moved the cursor. I built on to his answer and an answer here to form a complete solution. It may not be best practice due to setting the EditText in the onTextChanged() method but it works.
/* don't allow user to move cursor while entering price */
mEditText.setMovementMethod(null);
mEditText.addTextChangedListener(new TextWatcher() {
private String current = "";
NumberFormat formatter = NumberFormat.getCurrencyInstance();
private double parsed;
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!s.toString().equals(current)) {
/* remove listener to prevent stack overflow from infinite loop */
mEditText.removeTextChangedListener(this);
String cleanString = s.toString().replaceAll("[$,]", "");
try {
parsed = Double.parseDouble(cleanString);
}
catch(java.lang.NumberFormatException e) {
parsed = 0;
}
formatter.setMaximumFractionDigits(0);
String formatted = formatter.format(parsed);
current = formatted;
mEditText.setText(formatted);
/* add listener back */
mEditText.addTextChangedListener(this);
/* print a toast when limit is reached... see xml below.
* this is for 6 chars */
if (start == 7) {
Toast toast = Toast.makeText(getApplicationContext(),
"Maximum Limit Reached", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}
}
A quick way to ensure the user doesn't enter invalid information is to edit the xml. For my program, a limit of 6 number characters was set.
<!-- it says maxLength 8 but it's really 6 digits and a '$' and a ',' -->
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number|textVisiblePassword"
android:maxLength="8"
android:digits="0123456789"
android:id="#+id/mEditText"
android:hint="Price"/>

Why don't you format the amount using currencyFormat and then take out the .00 from the String.
private static final ThreadLocal<NumberFormat> currencyFormat = new ThreadLocal<NumberFormat>() {
#Override
protected NumberFormat initialValue() {
return NumberFormat.getCurrencyInstance();
}
};
currencyFormat.get().format( < your_amount_here > )

etProductCost.addTextChangedListener(new TextWatcher() {
#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().length() == 1){
//first number inserted.
if (s.toString().equals(getString(R.string.currency_symbol))){
//if it is a currecy symbol
etProductCost.setText("");
}else {
etProductCost.setText(getString(R.string.currency_symbol) + s.toString());
etProductCost.setSelection(s.toString().length());
}
return;
}
//set cursor position to last in edittext
etProductCost.setSelection(s.toString().length());
}
#Override
public void afterTextChanged(Editable s) {}
});

Related

How to make a formated EditText start from Right to Left using TextWatcher?

What I have:
I have an EditText which accepts decimal input and I setted the default value in the XML to 0.00 (if there is no input yet)
If the user press 1, then the value change to 1. If he needs to enter decimal value then he must press the dot . on the keyboard.
What I want:
I want to auto format the EditText in a decimal format 0.00, so if a user press 1 if becomes 0.01 instead of 1 (Like in the PAYPAL App). If he entered 100, then the value in the EditText must be formatted as 1.00.
I know this can be done by using TextWatcher but I don't know how to achieve this.
End Result Comparison:
WHAT I HAVE
1 = 1
11 = 11
222 = 222
WHAT I NEED
1 = 0.01
11 = 0.11
222 = 2.22
UPDATE:
My actual TextWatcher looks like below just to set the default value to 0.00 if the user deletes all inputs (to prevent error on calculated functions).
private class EditTextListener implements TextWatcher {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
if (editText.getText().toString().equals("") || editText.length() < 1){
editText.setText("0.00");
editText.post(() -> editText.setSelection(editText.getText().length()));
} else {
BigDecimal amount = new BigDecimal(editText.getText().toString());
}
}
}
as you described you need to divide it by 100 with decimal points:
#Override
public void afterTextChanged(Editable s) {
if (editText.getText().toString().equals("") || editText.length() < 1) {
editText.setText("0.00");
editText.post(() -> editText.setSelection(editText.getText().length()));
} else {
double amount = Double.parseDouble(editText.getText().toString());
editText.setText(String.format("%.2f", (amount / 100.0));
}
}
Try use this code
edtQtdVolume.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
edtQtdVolume.removeTextChangedListener(this);
String cleanString = s.toString().replaceAll("[R$,.]", "");
double parsed = Double.parseDouble(cleanString);
Locale locale = new Locale("en", "US");
NumberFormat nf = NumberFormat.getNumberInstance(locale);
DecimalFormat formatter = (DecimalFormat) nf;
formatter.applyPattern("#0.00");
String formatted = formatter.format((parsed/100));
edtQtdVolume.setText(formatted);
edtQtdVolume.setSelection(formatted.length());
edtQtdVolume.addTextChangedListener(this);
lista.get(position).setQtdVolumeInformadoColeta(Double.valueOf(formatted));
}
#Override
public void afterTextChanged(Editable s) {
}
});

How to default an EditText to integer but allow decimal input?

I am using an EditText to allow a user to input a value that is stored in a Double.
However, by default, Doubles look like "0.0" and it's a little annoying for a user to backspace over the extra decimal if it's not used. Is there a way to force-display whole numbers to look like "0" and only show the decimal if the user actually decides to use it?
Current code:
myEditText = (EditText) view.findViewById(R.id.my_edittext);
myEditText.setText(myVariable + "");
myEditText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
String temp = s.toString();
if (s.length() > 0){
if (OtherMethods.isDouble(temp)) {
myVariable = Double.parseDouble(temp);
}
else {
myVariable = 0.0;
}
}
else {
myVariable = 0.0;
}
}
});
The XML:
<EditText
android:id="#+id/my_edittext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:ems="10"
android:hint="Input Value"
android:imeOptions="actionDone"/>
To achieve this you can use NumberFormat
EditText yourEditText = (EditText) findViewById(R.id.editTextID);
//dummy data, will have user's value
double aDouble = 4.0;
//formats to show decimal
NumberFormat formatter = new DecimalFormat("#0");
//this will show "4"
yourEditText.setText(formatter.format(aDouble));
Make sure to validate the user's input. Also, this will only modify what is displayed and not the value itself.
Parsing Double to String, then String to Int:
String stringparsed = YourDouble + "";
int intparsed = Integer.parseInt(stringparsed);
Using substring to cut the string from a startIndex to finalIndex:
String stringparsed = YourDouble + "";
String final = stringparsed.substring(0,1); //for example, if the double was 0.0, the result is 0

How Edittext can accept only two numbers after decimal point

I am trying to add only two numbers after a decimal point input in an EditText.
So I implemented a TextWatcher to check the string during input.
The function I am using below works amazing but has one major flaw. When you input any value,then you add a decimal point,delete that decimal point and proceed to add more values,only 3 values are accepted as input.
Case example: I input 300. but then I realize I wanted to input 3001234567, so I delete the decimal point . and proceed to add 1234567 to 300, Only 123 will be accepted and the rest ignored.
How should i handle this? Any suggestions will be appreciated.
My code:
price.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
public void afterTextChanged(Editable arg0) {
if (arg0.length() > 0) {
String str = price.getText().toString();
price.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DEL) {
count--;
InputFilter[] fArray = new InputFilter[1];
fArray[0] = new InputFilter.LengthFilter(100);
price.setFilters(fArray);
//change the edittext's maximum length to 100.
//If we didn't change this the edittext's maximum length will
//be number of digits we previously entered.
}
return false;
}
});
char t = str.charAt(arg0.length() - 1);
if (t == '.') {
count = 0;
}
if (count >= 0) {
if (count == 2) {
InputFilter[] fArray = new InputFilter[1];
fArray[0] = new InputFilter.LengthFilter(arg0.length());
price.setFilters(fArray);
//prevent the edittext from accessing digits
//by setting maximum length as total number of digits we typed till now.
}
count++;
}
}
}
});
Try this:
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String input = s.toString();
if(input.contains(".") && s.charAt(s.length()-1) != '.'){
if(input.indexOf(".") + 3 <= input.length()-1){
String formatted = input.substring(0, input.indexOf(".") + 3);
editReceiver.setText(formatted);
editReceiver.setSelection(formatted.length());
}
}else if(input.contains(",") && s.charAt(s.length()-1) != ','){
if(input.indexOf(",") + 3 <= input.length()-1){
String formatted = input.substring(0, input.indexOf(",") + 3);
editReceiver.setText(formatted);
editReceiver.setSelection(formatted.length());
}
}
}
Please note, german decimals are , seperated instead of . seperated
You can remove that else part, if it is not needed.

How can I get the first 10 digits from EditText, and set this digits in a TextView?

I have a field filled with an EditText control, it figures: 475759403048575663648495004945757590.
What can I use to choose the first 10 numbers from this EditText:
and then, insert the numbers 4757594030, in the TextView?
You can substring the string to 10 characters.
String s = somestring.substring(0,10);
So this will return the first 10 characters, and now you can put the value S in your control!
You can put a textwatcher to the edittext, then count as the edit text is being edited, when you get to the number of characters (10 in this case), you can then display those characters.
Example
TextView textView = ....
edittext.addTextChangedListener(new TextWatcher(){
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) { }
#Override
public void afterTextChanged(Editable textVal) {
String inputText = textVal.toString();
if (inputText.length() == 10) {
textView.setText(inputText);
}
}
});

RGB to HEX not converting correctly

I am trying to convert RGB to HEX but my EditText which holds the Hex value does not show 0
This is my code:
etHexVal = (EditText) findViewById(R.id.etHex);
if (etHexVal.length() == 6) { //has 000000
}
if (etHexVal.length() < 6) { //anything else
Toast.makeText(getApplicationContext(), "Please enter SIX characters/numbers combination", 2000).show();
}
etHexVal.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
String filtered_str = s.toString();
if (filtered_str.matches(".*[^A-F^0-9].*")) {
filtered_str = filtered_str.replaceAll("[^A-F^0-9]", "");
s.clear();
s.append(filtered_str);
Toast.makeText(getApplicationContext(), "Only A-F and 0-9 is allowed", 2000).show();
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
private int getColorFromSeekbars()
{
return Color.argb(255, redSeek.getProgress(), greenSeek.getProgress(), blueSeek.getProgress());
}
private String displayHexVal() {
String k = "" + redSeek.getProgress() + greenSeek.getProgress() + blueSeek.getProgress() + "";
Toast.makeText(getApplicationContext(), k, 2000).show();
String strColor = String.format("#%06X", 0xFFFFFF & Integer.valueOf(k));
return strColor;
}
I have three Seekbars and if RED seekbar is 0 and GREEN seekbar is 0 and BLUE seekbar is 146, I want to display 000092 in the etHexVal edittext but it only shows 00009. If RED is 0 GREEN is 85 and BLUE is 146 the etHexVal displays 014C9 instead of #005592. What is going wrong here?
If I understand your question correctly, you're not getting the correct values in your String. Try doing the following:
In your displayHexVal() replace String k ... with:
public String k = getHexFromInt(redSeek.getProgress()) + getHexFromInt(greenSeek.getProgress()) + getHexFromInt(blueSeek.getProgress());
and add the method below:
public String getHexFromInt(int val){
StringBuilder sb = new StringBuilder();
sb.append(Integer.toHexString(val));
if (sb.length() < 2) {
sb.insert(0, '0'); // add leading zero if necessary
}
String hex = sb.toString();
return hex;
}
To revert the String back to ints, do the following (Note: you may want to add error-handling here):
public int[] getIntsFromHex(String hex){
int[] results = new int[3];
results[0] = Integer.parseInt(hex.substring(0,2),16);
results[1] = Integer.parseInt(hex.substring(2,4),16);
results[2] = Integer.parseInt(hex.substring(4,6),16);
return results;
}

Categories

Resources