3
votes

Comment séparer les nombres par des virgules dans EditText

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.


1 commentaires

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/...


4 Réponses :


2
votes

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 .


2 commentaires

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.



3
votes

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

            }
        });

Voir ce post


0 commentaires

2
votes

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.


0 commentaires

0
votes

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.


0 commentaires