EditText CurrencyFormat without symbol Android - java

The code below produce an stackoverflow error. The idea is to format the amount when or after user type an amount.
500 -> 500.00
1000 -> 1 000.00
29999.55-> 29 999.55
..
..
..
edit_amount.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
if (edit_amount.getText().toString().length()>0){
edit_amount.setText(
currencyFormat(edit_amount.getText().toString()));
}else {}
}
});
public String currencyFormat(String number){
String credits="";
try {
//en, us
if (TextUtils.isEmpty(MyApplication.pref.GetPreferences("AppCurrency"))){
credits = NumberFormat.getCurrencyInstance(new Locale("fr", "FR")).format(Double.valueOf(number));
}else {
if (MyApplication.pref.GetPreferences("AppCurrency").equals("Euro")) {
credits = NumberFormat.getCurrencyInstance(new Locale("fr", "FR")).format(Double.valueOf(number));
} else {
credits = NumberFormat.getCurrencyInstance(new Locale("en", "US")).format(Double.valueOf(number));
}
}
}catch(Exception ex){
credits = "mCredits";
}
return credits;
}

Your code doesn't work because when you call edit_amount.setText(...) then the afterTextChanged(Editable s) is triggered and then edit_amount.setText(...) is triggered and so on. You need to change your logic to do what you want and avoid stack overflow.
For example you could unregister TextWatcher, setText and then register it again.
Alternatively, you can set a flag so that your TextWatcher knows when you change the text yourself and then instruct TextWatcher to ignore it.

To avoid recursive invocation of afterTextChanged callback you can set up additional chek. Smth like this
#Override
public void afterTextChanged(Editable s) {
if (et.getText().toString().length() > 0) {
String src = et.getText().toString();
String origin = currencyFormat(src);
if(!src.equals(origin)) {
et.setText(currencyFormat(et.getText().toString()));
}
}
}

Try below code :
private String current = "";
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(!s.toString().equals(current)){
[your_edittext].removeTextChangedListener(this);
String cleanString = s.toString().replaceAll("[$,.]", "");
double parsed = Double.parseDouble(cleanString);
String formatted = NumberFormat.getCurrencyInstance().format((parsed/100));
current = formatted;
[your_edittext].setText(formatted);
[your_edittext].setSelection(formatted.length());
[your_edittext].addTextChangedListener(this);
}
}

Related

How can I modify the input of multiple EditTexts at the same time, as I only modify one?

I have multiple EditTexts and I want to change the input of all of them at the same time, as I modify only one.(all of them take decimal numbers as input)
I stored the EditTexts in an array named 'editTexts'.
Here's what I tried
//Set the listener for each element
for (int i=0; i<editTexts.length; i++) {
final int finalI = i;
editTexts[i].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 the editText which is currently edited is empty, set the input for all the rest to be '0.0'
if (editTexts[finalI].getText().toString().trim().length() == 0) {
for(EditText e : editTexts) {
if (e == editTexts[finalI])
continue;
e.setText("0.0");
}
} else {
float no = Float.parseFloat(s.toString() + "");
//Set the input of all the other editTexts to be the decimal number entered, multiplied by 2
for(EditText e : editTexts){
if(e == editTexts[finalI])
continue;
e.setText(no*2+"");
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
})
}
In this case the multiplication coefficient is just an example, it's not always gonna be 2. I used it just to test it out.
For some reason, when I change the input value, the app freezes.
Any help? Thanks!
Use LiveData to store your user input values.
Once it's value changes you can set value to each EditText. I think it is an easy way to implement.
Try it like this:
// et_x1, et_x2 and et_x3 are ids of EditTexts
//set inputType for all EditTexts as numberDecimal
EditText editText1 = findViewById(R.id.et_x1);
final EditText editText2 = findViewById(R.id.et_x2);
final EditText editText3 = findViewById(R.id.et_x3);
editText1.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) {
String value = s.toString();
double x;
if (!value.equals("")) {
x = Double.parseDouble(value);
} else {
x = 0.0;
}
editText2.setText(Editable.Factory.getInstance().newEditable((String.valueOf(Math.pow(x, 2)))));
editText3.setText(
Editable.Factory.getInstance().newEditable((String.valueOf(Math.pow(x, 3)))));
}
#Override
public void afterTextChanged(Editable s) {
}
});
Hope it helps you!

How to add 3 decimal places Currency formatting to edittext Using TextWatcher Android

I want to add 3 decimal places currency formatting to EditText using TextWatcher
at the beginning, value is 0.000 and the number should change right to left
eg: if I pressed 1,2,3,4,5 in order value should appear as this 12.345
following code is worked only for 2 decimal places. Please anyone helps me how to change this code for 3 decimal places or another solution
public class CurrencyTextWatcher implements TextWatcher {
boolean mEditing;
Context context;
public CurrencyTextWatcher() {
mEditing = false;
}
public synchronized void afterTextChanged(Editable s) {
if(!mEditing) {
mEditing = true;
String digits = s.toString().replaceAll("\\D", "");
NumberFormat nf = NumberFormat.getCurrencyInstance();
try{
String formatted = nf.format(Double.parseDouble(digits)/100);
s.replace(0, s.length(), formatted);
} catch (NumberFormatException nfe) {
s.clear();
}
mEditing = false;
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
public void onTextChanged(CharSequence s, int start, int before, int count) { }
}
Divide 1000 instead of 100 and also setMinimumFractionDigits for NumberFormat as 3.
public class CurrencyTextWatcher implements TextWatcher {
boolean mEditing;
Context context;
public CurrencyTextWatcher() {
mEditing = false;
}
public synchronized void afterTextChanged(Editable s) {
if(!mEditing) {
mEditing = true;
String digits = s.toString().replaceAll("\\D", "");
NumberFormat nf = NumberFormat.getCurrencyInstance();
nf.setMinimumFractionDigits(3);
try{
String formatted = nf.format(Double.parseDouble(digits)/1000);
s.replace(0, s.length(), formatted);
} catch (NumberFormatException nfe) {
s.clear();
}
mEditing = false;
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
public void onTextChanged(CharSequence s, int start, int before, int count) { }
}

TextWatcher not detecting delete key

I have a TextWatcher that places a percent sign after numbers in an EditText. That part works fine. The problem is if the user makes a mistake and needs to delete the numbers in the editText, the percent sign does not allow any deletions. below is my code:
#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) {
editText.removeTextChangedListener(this);
try {
String originalString = s.toString();
if (originalString.contains("%")) {
originalString = originalString.replaceAll("%", "");
}
String formattedString = originalString + "%";
//setting text after format to EditText
editText.setText(formattedString);
editText.setSelection(editText.getText().length());
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
editText.addTextChangedListener(this);
}
I believe I need an OnKeyListener but don't know exactly how to implement it. this is what I did with the OnKeyListener but it doesn't work:
boolean keyDelete
#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(!keyDelete) {
editText.removeTextChangedListener(this);
try {
String originalString = s.toString();
if (originalString.contains("%")) {
originalString = originalString.replaceAll("%", "");
}
String formattedString = originalString + "%";
//setting text after format to EditText
editText.setText(formattedString);
editText.setSelection(editText.getText().length());
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
editText.addTextChangedListener(this);
}
}
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DEL){
keyDelete = true;
}else{
keyDelete = false;
}
return false;
}
Any help on this is greatly appreciated..
Your code works fine if a user sets a cursor before '%' symbol. The issue is that after text formatting you set selection to the end of a text.
editText.setSelection(editText.getText().length());
In a case, when a user pushes the delete button without replacing a cursor, he is deleting '%' symbol, but your code returns '%' symbol back each time. This is because feels like:
the percent sign does not allow any deletions
To solve your issue refactor your code to set selections before '%' symbol:
#Override
public void afterTextChanged(Editable s) {
editText.removeTextChangedListener(this);
try {
String originalString = s.toString();
if (originalString.contains("%")) {
originalString = originalString.replaceAll("%", "");
}
String formattedString = originalString + "%";
//setting text after format to EditText
editText.setText(formattedString);
if (formattedString.length() >= 1) {
editText.setSelection(editText.getText().length() - 1);
}
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
editText.addTextChangedListener(this);
}

How to check first 2characters of String in Android

In my application, I want to get a phone number from the user and if the first 2 characters of this number are 09, I want to show Toast.
I wrote the code below, but it always shows me the Toast message.
My code:
phoneNumberPage_phoneEdtTxt.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() < 11) {
enableDisableBtn(0.3f, false);
} else {
hideKeyboard(activity);
enableDisableBtn(1.0f, true);
}
}
#Override
public void afterTextChanged(Editable s) {
if (s.toString().trim().length()==1){
if (!s.equals("0")){
Toast.makeText(context, "NOOOOOO", Toast.LENGTH_SHORT).show();
}
}
}
});
}
How can I do it? Can you please help me?
using startsWith
if(s.startsWith("09")){
or you can use matches with regex
if(s.matches("09(.*)"))
You should check String reference especially substring method. In your case you can use substring like this:
String twoFirstCharacters = string.substring(0, 2);
if (twoFirstCharacters.equals("09")) {
// here we go
}
Use String.startsWith() method
#Override
public void afterTextChanged(Editable s) {
if (s!=null&& !s.toString().trim().isEmpty()){ // make sure String value is there
if (!s.startsWith("09")){ // check string qualifies your requirement
Toast.makeText(context, "NOOOOOO", Toast.LENGTH_SHORT).show();
}
}
}

How to update an EditText to convert input into currency? (Android Newbie)

I have a number of EditText's with an inputType="numberDecimal" and i'm wanting to change the input into currency (TextWatcher maybe?). Can anyone help with this? 99% of my project is done bar this. Thanks guys.
try below code:-
tv.addTextChangedListener(new TextWatcher()
{
private String current = "";
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
if(!s.toString().equals(current))
{
if(tv.getText().toString().trim().length()>0)
{
tv.removeTextChangedListener(this);
String formated = tv.getText().toString().trim().replace("$", "");
current = formated;
tv.setText("$"+formated);
tv.setSelection(formated.length()+1);
tv.addTextChangedListener(this);
}
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
#Override
public void afterTextChanged(final Editable s)
{
}
});

Categories