I want to format my EditText after every typing.
(e.g: User types 1234 and I correct as 1.234,00)
With this function, I format String correctly and I can see it on Toast message. But whenever I try to set text to edittext, it gives error after typing second number.
This is my format function:
public String moneySeperator(double moneyAmount){
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setGroupingSeparator('.');
symbols.setDecimalSeparator(',');
DecimalFormat decimalFormat = new DecimalFormat("#,###.00", symbols);
String prezzo = decimalFormat.format(moneyAmount);
return prezzo;
}
Here is my EditText listener:
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
editText.removeTextChangedListener(this);
if(!editText.getText().toString().isEmpty()){
String userInput = editText.getText().toString();
Toast.makeText(Denemey.this, ""+moneySeperator(Double.parseDouble(userInput)), Toast.LENGTH_SHORT).show();
editText.setText(""+moneySeperator(Double.parseDouble(userInput)));
}
editText.addTextChangedListener(this);
}
});
Here is the error: (It points editText.setText line)
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.incidijital.kdvtevkifati, PID: 7500
java.lang.NumberFormatException: For input string: "15,00"
at java.lang.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1306)
at java.lang.Double.parseDouble(Double.java:547)
at com.myproject.dd$1.afterTextChanged(Denemey.java:46)
UPDATED: I made my code really shorter. When I try a double like 1234.50
it works well on printing, but I think there is something wrong about afterTextChanged listener. My first 4 types (e.g: 1,234) works well, after I add more it crash because of Double.parseDouble casting, but there is no comma.
I removed formatter function.
#Override
public void afterTextChanged(Editable editable) {
editText.removeTextChangedListener(this);
java.text.NumberFormat formatter = java.text.NumberFormat.getInstance(java.util.Locale.GERMANY);
if(!editText.getText().toString().isEmpty()){
double myDob = Double.parseDouble(""+editable);
editText.setText(""+(formatter.format(myDob)));
editText.setSelection(editText.getText().length());
}
editText.addTextChangedListener(this);
}
});
You have to remove all non numeric chars before parsing it as double. I am assuming here that your #moneySeperator working fine for format .
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
editText.removeTextChangedListener(this);
String userInput = editText.getText().toString().replaceAll("[^0-9]", "");
if(!userInput.isEmpty()){
Toast.makeText(Denemey.this, ""+moneySeperator(Double.parseDouble(userInput)), Toast.LENGTH_SHORT).show();
editText.setText(""+moneySeperator(Double.parseDouble(userInput)));
}else{
editText.setText("")
}
editText.addTextChangedListener(this);
}
});
Related
I am trying to implement something similar to a code editor where keywords are automatically highlighted. I am going to have a string array and I want to change the color and font of the editText string when the user types the text and it matches a string from the string array. I am using the addTextChangeListener but the text of the whole editText changes. I want just the matched word to be highlighted. Here is my code:
inputCodeEditText.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) {
if (s.toString().contains("for"))
{
inputCodeEditText.setTextColor(getResources().getColor(R.color.indigo));
}
}
});
I understand I have to use spans but the code crashes. Can anyone help me with the correct usage of spannable strings with addTextChangedListener() ?
Use addTextChangeListener API eg:
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) {
// The changed text comes in "s" parameter.
// Here you can watch the changes and take an action you want...
}
#Override
public void afterTextChanged(Editable s) {
}
});
Trying to get an integer from Edit Text entered by the user(such as Total Amount) and to display it by multiplying with value(such as 5%) and display it using TextView automatically.
For the 1st part i.e. simply displaying the integer from EditText to TextView got NumberFormatException Error.
'''
temp = (Integer.parseInt(editText.getText().toString()));
textView.setText(temp);
'''
And for the second part i.e. automatically displaying the value from EditText to TextView, no idea how to approach.
Just use textwatcher and put the logic in it. Just make sure change the id of edittext and textview
et.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) { }
#Override
public void afterTextChanged(Editable s) {
String value = s.toString();
double outputValue = Integer.parseInt(value) * 0.05;
textView.setText(String.valueOf(outputValue));
}
});
Make sure in edittext that it only capture the numerical value.
you could try this approach
editText.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) { }
#Override
public void afterTextChanged(Editable s) {
String userInputText = s.toString();
try {
val userInputAsNumbger = userInputText.toInt();
}catch (e:NumberFormatException){
print(e.message)
}
}
});
to ensure it doesn't error
I have to convert some numeric editText in double and after text changed do a simple math operation. Everything works fine except On Text Changed: it crash whatever I do (also to change TextView with "hello world").
Here's my code:
hEditText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
{
Double hDouble = Double.parseDouble(hEditText.toString());
Double bDouble = Double.parseDouble(bEditText.toString());
Double mDouble = Double.parseDouble(mEditText.getText().toString());
Double miDouble = Double.parseDouble(miEditText.getText().toString());
lResult.setText("" + Math.sqrt((hDouble * hDouble) + (bDouble * bDouble)));
}
#Override
public void afterTextChanged(Editable editable) {
}
});
LOG
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.cosmo.fisicapp, PID: 21198
java.lang.NumberFormatException: empty String
at java.lang.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1071)
at java.lang.Double.parseDouble(Double.java:547)
at com.example.cosmo.fisicapp.Equilibrio$1.afterTextChanged(Equilibrio.java:47)
at android.widget.TextView.sendAfterTextChanged(TextView.java:8525)
at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:10788)
at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:1222)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:583)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:509)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:508)
at android.text.method.NumberKeyListener.onKeyDown(NumberKeyListener.java:121)
at android.widget.TextView.doKeyDown(TextView.java:6533)
at android.widget.TextView.onKeyDown(TextView.java:6323)
at android.view.KeyEvent.dispatch(KeyEvent.java:2742)
at android.view.View.dispatchKeyEvent(View.java:9949)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1667)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1667)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1667)
at android.widget.ScrollView.dispatchKeyEvent(ScrollView.java:391)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1667)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1667)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1667)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1667)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1667)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1667)
at com.android.internal.policy.DecorView.superDispatchKeyEvent(DecorView.java:439)
at com.android.internal.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1861)
at android.app.Activity.dispatchKeyEvent(Activity.java:3141)
at android.support.v7.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:535)
at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:59)
at android.support.v7.app.AppCompatDelegateImpl$AppCompatWindowCallback.dispatchKeyEvent(AppCompatDelegateImpl.java:2530)
at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:353)
at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4742)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4713)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4249)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4302)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4268)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4395)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4276)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4452)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4249)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4302)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4268)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4276)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4249)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6676)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6650)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6611)
at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:3917)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
hEditText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
{
if(!charSequence.equals("")){
Double hDouble = Double.parseDouble(charSequence.toString());
Double bDouble = Double.parseDouble(charSequence.toString());
Double mDouble = Double.parseDouble(charSequence.getText().toString());
Double miDouble = Double.parseDouble(charSequence.getText().toString());
lResult.setText("" + Math.sqrt((hDouble * hDouble) + (bDouble * bDouble)));
}
}
#Override
public void afterTextChanged(Editable editable) {
}
});
Try moving your code to :
#Override
public void afterTextChanged(Editable editable) {
Double hDouble = Double.parseDouble(hEditText.toString());
Double bDouble = Double.parseDouble(bEditText.toString());
Double mDouble = Double.parseDouble(mEditText.getText().toString());
Double miDouble = Double.parseDouble(miEditText.getText().toString());
lResult.setText("" + Math.sqrt((hDouble * hDouble) + (bDouble * bDouble)));
}
Trying changing the following lines:
Double hDouble = Double.parseDouble(hEditText.toString()); to
Double hDouble = Double.parseDouble(hEditText.getText().trim()); and the other lines
Your app would crash every time the parser doesn't produce a Double. Enclose every transformation from String to Double in a try/catch. If the user types anything other than numbers or ., or clears the EditText
then the app will crash
The method afterTextChanged can't crash because it is empty. The method onTextChanged, on the other hand, which makes extensive use of Double.parseDouble(String) most definitely can, as this will throw a NumberFormatException if you give it something that can't be converted to a double. See the documentation.
To get around this, one possibility is to make a helper method so that you're not putting try-catch blocks everywhere and decide either to catch the exception and return a default value (such as 0D) or let it propagate.
For example:
private double toDouble(String raw) {
double val;
try {
val = Double.parseDouble(raw);
} catch (NumberFormatException e) {
val = 0D;
}
return val;
}
then your code in onTextChanged becomes
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)
{
Double hDouble = toDouble(hEditText.toString());
Double bDouble = toDouble(bEditText.toString());
Double mDouble = toDouble(mEditText.getText().toString());
Double miDouble = toDouble(miEditText.getText().toString());
lResult.setText("" + Math.sqrt((hDouble * hDouble) + (bDouble * bDouble)));
}
I want to know what is the locale of input text in edittext!
However i tried to get the keyboard locale but that wasn't helpful.
I don't want to type english in the edittext so help me!
I want user to know that he/she can't type english!
Sorry for my bad english!
Here is my code :
edtUsernameLogin.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
if (editable.toString().isEmpty()) {
mtfUsernameLogin.setLabelColor(G.resources.getColor(R.color.cpb_white), "نام کاربری");
} else {
String locale = G.inputMethodManager.getCurrentInputMethodSubtype().getLocale();
if (locale.equals("fa") || locale.equals("ar")) {
mtfUsernameLogin.setLabelColor(G.resources.getColor(R.color.sPink), "نام کاربری باید انگلیسی باشد !");
} else {
mtfUsernameLogin.setLabelColor(G.resources.getColor(R.color.sGreen), "نام کاربری");
}
}
}
});
The Solution is :
InputFilter usernameFilter = new InputFilter() {
#Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String blockCharacterSet = " اآبپتثجچحخدذرزژسشصضطظعغفقکگلمنوهی";
if (blockCharacterSet.contains(source)) {
edtNameEdit.setHintTextColor(getResources().getColor(R.color.grey));
edtNameEdit.setHint("نام و نام خانوادگی");
return source.toString();
} else {
edtNameEdit.setHintTextColor(getResources().getColor(R.color.sPink));
edtNameEdit.setHint("نام و نام خانوادگی باید فارسی باشد!");
return "";
}
}
};
edtNameEdit.setFilters(new InputFilter[]{usernameFilter});
And important line :
edtNameEdit.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
I want to check if a String (coming from an EditText) is part of a String Array and I need the index. I have got a TextWatcher added as TextChangedListener like the following:
inside Activity-Class:
private String[] randomSpanishWords = { "pueblo", "madre" };
private TextWatcher ETListener = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
int index = Arrays.asList(randomSpanishWords).indexOf(charSequence);
}
#Override
public void afterTextChanged(Editable editable) {
}
};
in onCreate():
editText1.addTextChangedListener(ETListener);
No matter what Im typing in the EditText, index is always -1. What am I missing?
Try to convert your charSequence to String with
charSequence.toString()
Or use CharSequence for your array
private CharSequence[] randomSpanishWords = { "pueblo", "madre" };