J'ai un EditText qui a un inputType de nombre . Pendant que l'utilisateur tape, je souhaite séparer les nombres par des virgules. Voici une petite illustration:
123 serait représenté par 123
1234 serait représenté par 1 234
12345 serait représenté par 12345
... et ainsi de suite.
J'ai essayé d'ajouter une virgule avec TextWatcher comme indiqué ci-dessous:
EditText edittext = findViewById(R.id.cashGiven); 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.setText(separateWithComma(editText.getText().toString().trim())); } });
Coller la méthode separWithComma ()
ici ferait cela question extra longue mais là, ça marche: je l'ai testé sur Eclipse. Je pense que addTextChangedListener ne fonctionne pas de cette façon car mon application se fige (puis se bloque beaucoup plus tard) lorsque je fais cela.
Y a-t-il une meilleure façon d'y parvenir? Merci en prévision d'une réponse positive.
4 Réponses :
Essayez d'utiliser String.format
au lieu de ce que vous avez maintenant.
Remplacez ceci:
editText.setText(String.format("%,d", your number));
par ceci:
editText.setText(separateWithComma(editText.getText().toString().trim()));
Autre chose - votre l'application peut avoir ce plantage parce que chaque fois que vous appelez setText ()
dans afterTextChanged
, un autre afterTextChanged
est appelé et créera essentiellement un infini boucle. Si tel est votre problème, vous pouvez trouver une bonne solution ici .
Même résultat, l'application a commencé à se figer comme un fou. Je ne pense pas que je devrais utiliser un addTextChangedListener. Je pense que c'est le problème.
@TaslimOseni Afin d'éviter que l'application ne se fige, vous devez désactiver votre textChangedListener lorsque vous faites setText ("")
et l'activer à nouveau par la suite.
Essayez ce code:
et.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // TODO Auto-generated method stub } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO Auto-generated method stub } @Override public void afterTextChanged(Editable s) { et.removeTextChangedListener(this); try { String givenstring = s.toString(); Long longval; if (givenstring.contains(",")) { givenstring = givenstring.replaceAll(",", ""); } longval = Long.parseLong(givenstring); DecimalFormat formatter = new DecimalFormat("#,###,###"); String formattedString = formatter.format(longval); et.setText(formattedString); et.setSelection(et.getText().length()); // to place the cursor at the end of text } catch (NumberFormatException nfe) { nfe.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } et.addTextChangedListener(this); } });
J'ai obtenu deux bonnes réponses, mais je voulais juste ajouter ceci:
La raison pour laquelle j'ai été confronté à ce problème était parce que editText.setText (...) code> était appelé récursivement dans la fonction
afterTextChanged ()
de mon TextWatcher. Comme l’ont justement indiqué les répondants précédents, la solution consiste à arrêter temporairement le déclenchement de la méthode afterTextChanged ()
de cette façon:
boolean edit = true; ... @Override public void afterTextChanged(Editable editable){ if(edit){ edit = false; editText.setText(String.format("%,d", Integer.parseInt(getCommalessNumber(editText.getText().toString().trim())))); edit = true; } }
De cette façon, nous avons soigneusement serpenté notre chemin. Mais cela pose un NOUVEAU PROBLÈME:
En utilisant cette stratégie, nous supposons que la chaîne dans le EditText peut facilement être traduite en un int
. Au fur et à mesure que nous entrons plus de nombres, l'application planterait définitivement avec une NumberFormatException à cause des virgules. Par conséquent, il est important que nous trouvions un moyen de résoudre ce problème. Voici une méthode que j'ai écrite pour m'aider:
public String getCommalessNumber(String commaNumber){ String newNumber = ""; String[] split = commaNumber.trim().split(","); for(int i = 0; i < split.length; i++){ newNumber += split[i]; } return newNumber; }
Enfin, nous pouvons faire ceci:
private boolean edit = true; private int cursorPosition; ... @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { cursorPosition = editText.getText().toString().length() - editText.getSelectionStart(); } @Override public void onTextChanged(CharSequence s, int start, int before, int count){} @Override public void afterTextChanged(Editable editable){ if(edit){ edit = false; editText.setText(String.format("%,d", Integer.parseInt(editText.getText().toString().trim()))); edit = true; } //setting the cursor back to where it was editText.setSelection(editText.getText().toString().length() - cursorPosition); }
J'espère que cela vous aidera quelqu'un là-bas.
Pour ceux qui souhaiteraient utiliser cette approche, modifiez le type de retour de la méthode getCommalessNumber (String commaNumber) en String au lieu de int.
Le problème avec la définition du texte dans afterTextChanged est qu'il crée une boucle infinie consultez cette réponse stackoverflow.com/questions/9385081/...