Set EditText Digits Programatically with Filters - java

I am trying to set the digits value of an EditText programatically with pattern "9,999" (where 9 it's digit 0-9). So far I have:
final EditText editText = new EditText(v.getContext());
editText.setLayoutParams(params);
editText.setText("");
editText.setKeyListener(DigitsKeyListener.getInstance("0123456789"));
editText.setInputType(InputType.TYPE_CLASS_NUMBER);
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLenght)});
editText.addTextChangedListener(new TextWatcher() {
int len=0;
//int count=0;
#Override
public void afterTextChanged(Editable s) {
String str = editText.getText().toString();
if(str.length()==1&& len <str.length()){//len check for backspace
editText.append(",");
}
}
#Override
public void beforeTextChanged(CharSequence c, int arg1, int arg2, int arg3) {
String str = editText.getText().toString();
len = str.length();
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String str = editText.getText().toString();
}
});
Which is not best, because:
DigitsKeyListener won't accept "," separator.
When I type "1,0" and
then go 2x backspace I can type "11111". I have to go 3x backspace
and then when I type "11111" it will be "1,1111"
Any ideas?

You could try changing afterTextChange() method to this
#Override
public void afterTextChanged(Editable s) {
try {
String str = String.format("%,d", Long.parseLong(s.toString()
.replaceAll(",", "")));
int pos = editText.getSelectionStart();
editText.removeTextChangedListener(this);
editText.setText(str);
editText.setSelection(pos);
editText.addTextChangedListener(this);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}

Related

Convert formatCurrency (rupiah) to int

Here I have a method like this:
// method currency format
private String formatRupiah(Double number) {
Locale locale = new Locale("IND", "ID");
NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale);
String formatRupiah = numberFormat.format(number);
String[] split = formatRupiah.split(",");
int length = split[0].length();
String formatRupiahString = split[0].substring(0, 2) + " " + split[0].substring(2, length);
return formatRupiahString;
}
And also have this method to change the text that is in the edit text into the currency format:
private void editTextToFormatCurrency() {
etJumlah.addTextChangedListener(new TextWatcher() {
private String jumlahFormat = Objects.requireNonNull(etJumlah.getText()).toString().trim();
#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(jumlahFormat)) {
etJumlah.removeTextChangedListener(this);
String replace = s.toString().replaceAll("[Rp. ]", "");
if (!replace.isEmpty()) {
jumlahFormat = formatRupiah(Double.parseDouble(replace));
} else {
jumlahFormat = "";
}
etJumlah.setText(jumlahFormat);
etJumlah.setSelection(jumlahFormat.length());
etJumlah.addTextChangedListener(this);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
And now my question is how to change TextToFormatCurrencycto int or Integer without format currency ?
My goal of changing back to Integer or int is so I can upload to Firestore with data type number.
And the answer:
https://www.youtube.com/watch?v=TdgQW8T-KeQ&t (this is my video)
https://www.youtube.com/watch?v=NQOK2cam3js&t (this is my inspiration video)
String jumlahString = Objects.requireNonNull(String.valueOf(layoutJumlah.getEditText().getText()));
jumlahString = jumlahString.replaceAll("[^0-9]", "");
jumlah = Integer.parseInt(jumlahString);

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!

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);
}

Real time validation (before button click)

Is there any way to validate EditText fields in real time, before the user clicks a button.
For example, if I have
if (password.length() < 6) {
passwordwrapper.setError("Password must have at least 6 characters");
return;
}
and
if (!validateEmail(email)) {
emailwrapper.setError("Invalid email");
return;
}
with the validateEmail method being
private static final String EMAIL_PATTERN = "^[a-zA-Z0-9#_~!$&'()*+,;=:.\"(),:;<>#\\[\\]\\\\]+#[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$";
private Pattern pattern = Pattern.compile(EMAIL_PATTERN);
private Matcher matcher;
public boolean validateEmail(String email) {
matcher = pattern.matcher(email);
return matcher.matches();
}
How would I setup a TextWatcher or something else to validate it real time?
TextWatcher is used when an object of a type is attached to an Editable, its methods will be called when the text is changed. Here is the simplest way to set up Textwatcher:
EditText inputName = (EditText) findViewById(R.id.input_name);
EditText inputEmail = (EditText) findViewById(R.id.input_email);
EditTextinputPassword = (EditText) findViewById(R.id.input_password);
TextInputLayout inputLayoutEmail = (TextInputLayout) findViewById(R.id.input_layout_email);
inputName.addTextChangedListener(new MyTextWatcher(inputName));
inputEmail.addTextChangedListener(new MyTextWatcher(inputEmail));
inputPassword.addTextChangedListener(new MyTextWatcher(inputPassword))
Validate email
private boolean validateEmail() {
String email = inputEmail.getText().toString().trim();
if (email.isEmpty() || !isValidEmail(email)) {
inputLayoutEmail.setError(getString(R.string.err_msg_email));
requestFocus(inputEmail);
return false;
} else {
inputLayoutEmail.setErrorEnabled(false);
}
return true;
}
Check wheather email valid or not,
private static boolean isValidEmail(String email) {
return !TextUtils.isEmpty(email) && android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches();
}
Implements them,
private class MyTextWatcher implements TextWatcher {
private View view;
private MyTextWatcher(View view) {
this.view = view;
}
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
public void afterTextChanged(Editable editable) {
switch (view.getId()) {
case R.id.input_name:
validateName();
break;
case R.id.input_email:
validateEmail();
break;
case R.id.input_password:
validatePassword();
break;
}
}
}
I hope this will helpful for you.
can you try
Field1 = (EditText)findViewById(R.id.field1);
Field1.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) {
}
});

Overwrite text in EditText that has only 1 char is not working

I have multiple EditText views , each EditText view can contain only 1 char.
I need to make this rule - if I focus on one EditText , and it already has some text inside - then overwrite it . Also - if I press on delete key - I need the text to be cleared inside that view.
Then - I am checking if the EditText views has 1 empty cell - if not - checking if the EditText views has the correct letters.
I could have managed to make the clear button work, but I can not make the overwrite.
I did tried to use the TextWatcher , but it didn't work for me.
The EditText views are created dynamically .
Here is my code :
Answer.java
public class Answer {
String answer;
int answer_length;
int cell_margin=10;
int cell_size=180;
EditText[] EditTextArray;
public Answer(RelativeLayout rLayout1, Context context , String answer) {
this.answer = answer;
answer_length = answer.length();
if (answer_length>6){
cell_margin = 4;
cell_size = 110;
}
EditTextArray = new EditText[answer_length];
AnswerCell EditTextToSeeFirst = new AnswerCell(context,cell_size);
setListener(EditTextToSeeFirst);
EditTextArray[0] = EditTextToSeeFirst;
RelativeLayout.LayoutParams fparams = new RelativeLayout.LayoutParams
(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
fparams.setMargins(cell_margin,0,cell_margin,0);
rLayout1.addView(EditTextToSeeFirst, fparams);
for (int i = 1; i<answer_length ; i++){
RelativeLayout.LayoutParams lparams = new RelativeLayout.LayoutParams
(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lparams.addRule(RelativeLayout.LEFT_OF, EditTextArray[i-1].getId());
lparams.setMargins(cell_margin,0,cell_margin,0);
AnswerCell newEditText = new AnswerCell(context,cell_size);
setListener(newEditText);
EditTextArray[i] = newEditText;
rLayout1.addView(EditTextArray[i], lparams);
}
rLayout1.setGravity(Gravity.CENTER );
}
public void setListener(AnswerCell ac){
ac.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.d("test","test");
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
goToNextAvailableCell();
}
});
}
public void goToNextAvailableCell(){
for (int i = 0; i<answer_length ; i++) {
if(EditTextArray[i].getText().toString().matches("")){
EditTextArray[i].requestFocus();
return;
}
}
//Did not found empty cell
checkCorrectAnswer();
}
private void checkCorrectAnswer(){
String tryAnswer = "";
for (int i = 0; i<answer_length ; i++) {
tryAnswer += EditTextArray[i].getText().toString();
}
if (tryAnswer.matches(answer)){
Log.d("Correct !!","Correct Answer");
}
}
}
AnswerCell.java
public class AnswerCell extends EditText{
public AnswerCell(final Context context, int cell_size) {
super(context);
this.setId(View.generateViewId());
this.setBackgroundResource(R.color.answerCellBackground);
this.setHeight(cell_size);
this.setWidth(cell_size);
this.setFilters(new InputFilter[] {new InputFilter.LengthFilter(1)});
this.setCursorVisible(false);
this.setGravity(Gravity.CENTER);
this.setOnFocusChangeListener( new View.OnFocusChangeListener(){
public void onFocusChange( View view, boolean hasfocus){
if(hasfocus){
view.setBackgroundResource( R.drawable.answer_cell_has_focus);
}
else{
view.setBackgroundResource( R.drawable.answer_cell_lost_focus);
}
}
});
this.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
//You can identify which key pressed buy checking keyCode value with KeyEvent.KEYCODE_
if(keyCode == KeyEvent.KEYCODE_DEL) {
((EditText)v).setText("");
return true;
}
return false;
}
});
}
}
thanks !
It will work with this code
TextWatcher watcher = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//YOUR CODE
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//YOUR CODE
}
#Override
public void afterTextChanged(Editable s) {
String outputedText = s.toString();
// mOutputText.setText(outputedText);
}
};
Then add this in oncreate
mInputText.addTextChangedListener(watcher);
e2.addTextChangedListener(watcher);
e3.addTextChangedListener(watcher);
e4.addTextChangedListener(watcher);

Categories