web-dev-qa-db-fra.com

Masquer un EditText avec le format de numéro de téléphone Nan comme dans PhonenChumutils

Je veux faire le numéro de téléphone entré par l'utilisateur dans un fichier editext pour modifier dynamiquement le format chaque fois que l'utilisateur entrait un numéro. C'est-à-dire que lorsque l'utilisateur saisit jusqu'à 4 chiffres, comme 7144, l'editext affiche "714-4". J'aimerais que l'editext soit mis à jour de manière dynamique pour formater ### - ### - #### Chaque fois que l'utilisateur entrait un chiffre. Comment cela peut-il être fait? En outre, je manipule plus d'un édittexts.

25
eunique0216

Le moyen le plus simple de le faire est d'utiliser le fichier intégré Android phonenumberformattingtextwatcher .

Donc, fondamentalement, vous obtenez votre EditText en code et définissez votre observateur de texte comme celui-ci ...

EditText inputField = (EditText) findViewById(R.id.inputfield);
inputField.addTextChangedListener(new PhoneNumberFormattingTextWatcher());

Une bonne chose à propos de l'utilisation de PhonenumberFormattingTextwatcher est qu'elle formatera votre numéro de numéro correctement basé sur votre local.

75
brockoli

La réponse ci-dessus a raison mais cela fonctionne avec le pays spécifique. Si quelqu'un veut un tel numéro de téléphone formaté (### - ### - ####). Ensuite, utilisez ceci:

etPhoneNumber.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                    int digits = etPhoneNumber.getText().toString().length();
                    if (digits > 1)
                        lastChar = etPhoneNumber.getText().toString().substring(digits-1);
                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    int digits = etPhoneNumber.getText().toString().length();
                    Log.d("LENGTH",""+digits);
                    if (!lastChar.equals("-")) {
                        if (digits == 3 || digits == 7) {
                            etPhoneNumber.append("-");
                        }
                    }
                }

                @Override
                public void afterTextChanged(Editable s) {

                }
            });

Déclarer String lastChar = " " Dans votre activité.

Maintenant, ajoutez cette ligne en XML de votre EditText

Android:inputType="phone"

C'est tout.

édité : Si vous voulez que votre EditText Lenght limite 10 chiffres, ajoutez la ligne ci-dessous aussi:

Android:maxLength="12"

(C'est 12 parce que "-" prendra l'espace deux fois)

9
Rahul Sharma

Mon script, exemple pris d'ici description ici


<Android.support.design.widget.TextInputLayout
    Android:id="@+id/numphone_layout"
    app:hintTextAppearance="@style/MyHintText"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"

    Android:layout_marginTop="8dp">

    <Android.support.design.widget.TextInputEditText
        Android:id="@+id/edit_text_numphone"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:theme="@style/MyEditText"
        Android:digits="+() 1234567890-"
        Android:hint="@string/hint_numphone"
        Android:inputType="phone"
        Android:maxLength="17"
        Android:textSize="14sp" />
</Android.support.design.widget.TextInputLayout>

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
 TextInputEditText phone = (TextInputEditText) findViewById(R.id.edit_text_numphone);
 //Add to mask
    phone.addTextChangedListener(textWatcher);
}


   TextWatcher textWatcher = new TextWatcher() {
    private boolean mFormatting; // this is a flag which prevents the  stack overflow.
    private int mAfter;

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        // nothing to do here..
    }

    //called before the text is changed...
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        //nothing to do here...
        mAfter  =   after; // flag to detect backspace..

    }

    @Override
    public void afterTextChanged(Editable s) {
        // Make sure to ignore calls to afterTextChanged caused by the work done below
        if (!mFormatting) {
            mFormatting = true;
            // using US or RU formatting...
            if(mAfter!=0) // in case back space ain't clicked...
            {
                String num =s.toString();
                String data = PhoneNumberUtils.formatNumber(num, "RU");
                if(data!=null)
                {
                    s.clear();
                    s.append(data);
                    Log.i("Number", data);//8 (999) 123-45-67 or +7 999 123-45-67
                }

            }
            mFormatting = false;
        }
    }
};
2
Aleksandr K

Il suffit d'ajouter ce qui suit à éditext pour le numéro de téléphone pour obtenir un numéro de téléphone formaté (### - ### - ####)

Phone.addTextChangedListener(new TextWatcher() {

        int length_before = 0;

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            length_before = s.length();
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            if (length_before < s.length()) {
                if (s.length() == 3 || s.length() == 7)
                    s.append("-");
                if (s.length() > 3) {
                    if (Character.isDigit(s.charAt(3)))
                        s.insert(3, "-");
                }
                if (s.length() > 7) {
                    if (Character.isDigit(s.charAt(7)))
                        s.insert(7, "-");
                }
            }
        }
    });
1
chzahid

Les solutions ci-dessus ne reprennent pas l'espace de retour en évidence, donc lorsque vous supprimez certains chiffres après taper, le format a tendance à gâcher. Le code ci-dessous corrige ce problème.

phoneNumberEditText.addTextChangedListener(new TextWatcher() {

        int beforeLength;

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            beforeLength = phoneNumberEditText.length();
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            int digits = phoneNumberEditText.getText().toString().length();
            if (beforeLength < digits && (digits == 3 || digits == 7)) {
                phoneNumberEditText.append("-");
            }
        }

        @Override
        public void afterTextChanged(Editable s) { }
    });
1
Rancho Jr.

Masque dynamique pour Android à Kotlin. Celui-ci fonctionne bien et ajusté strictement le masque de numéro de téléphone. Vous pouvez fournir n'importe quel masque qui vous convient.

Edit : J'ai une nouvelle version qui verrouille l'événement des caractères non désirés saisis par l'utilisateur sur le clavier.

/**
 * Text watcher allowing strictly a MASK with '#' (example: (###) ###-####
 */
class PhoneNumberTextWatcher(private var mask: String) : TextWatcher {
    companion object {
        const val MASK_CHAR = '#'
    }

    // simple mutex
    private var isCursorRunning = false
    private var isDeleting = false

    override fun afterTextChanged(s: Editable?) {
        if (isCursorRunning || isDeleting) {
            return
        }
        isCursorRunning = true

        s?.let {
            val onlyDigits = removeMask(it.toString())
            it.clear()
            it.append(applyMask(mask, onlyDigits))
        }

        isCursorRunning = false
    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        isDeleting = count > after
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}

    private fun applyMask(mask: String, onlyDigits: String): String {
        val maskPlaceholderCharCount = mask.count { it == MASK_CHAR }
        var maskCurrentCharIndex = 0
        var output = ""

        onlyDigits.take(min(maskPlaceholderCharCount, onlyDigits.length)).forEach { c ->
            for (i in maskCurrentCharIndex until mask.length) {
                if (mask[i] == MASK_CHAR) {
                    output += c
                    maskCurrentCharIndex += 1
                    break
                } else {
                    output += mask[i]
                    maskCurrentCharIndex = i + 1
                }
            }
        }
        return output
    }

    private fun removeMask(value: String): String {
        // extract all the digits from the string
        return Regex("\\D+").replace(value, "")
    }
}
0
Maxime Claude

Ce code vous permet de saisir le numéro de téléphone avec le masque ### - ### - #### (sans espaces) et aussi ici est corrigé le problème avec la suppression des chiffres téléphoniques:

editText.addTextChangedListener(new TextWatcher() {
            final static String DELIMITER = "-";
            String lastChar;

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                int digits = editText.getText().toString().length();
                if (digits > 1)
                    lastChar = editText.getText().toString().substring(digits-1);
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                int digits = editText.getText().length();
                // prevent input dash by user
                if (digits > 0 && digits != 4 && digits != 8) {
                    CharSequence last = s.subSequence(digits - 1, digits);
                    if (last.toString().equals(DELIMITER))
                        editText.getText().delete(digits - 1, digits);
                }
                // inset and remove dash
                if (digits == 3 || digits == 7) {
                    if (!lastChar.equals(DELIMITER))
                        editText.append("-"); // insert a dash
                    else
                        editText.getText().delete(digits -1, digits); // delete last digit with a dash
                }
                dataModel.setPhone(s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {}
        });

Disposition:

<EditText
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:imeOptions="actionDone"
            Android:textAlignment="textStart"
            Android:inputType="number"
            Android:digits="-0123456789"
            Android:lines="1"
            Android:maxLength="12"/>
0
Konstantin Konopko

Voici ma solution

Comment exécuter une activité/fragment (f.e ineviewcated):

//field in class
private val exampleIdValidator by lazy { ExampleIdWatcher(exampleIdField.editText!!) }

exampleIdField.editText?.addTextChangedListener(exampleIdValidator)

Classe de validateur:

    import Android.text.Editable
    import Android.text.TextWatcher
    import Android.widget.EditText

    class ExampleIdWatcher(exampleIdInput: EditText) : TextWatcher {

        private var exampleIdInput: EditText = exampleIdInput

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        }

        override fun onTextChanged(userInput: CharSequence?, start: Int, before: Int, count: Int) {
            if (userInput!!.isNotEmpty() && !areSpacesCorrect(userInput)) {

                val stringTextWithoutWhiteSpaces: String = userInput.toString().replace(" ", "")

                val textSB: StringBuilder = StringBuilder(stringTextWithoutWhiteSpaces)

                when {
                    textSB.length > 8 -> {
                        setSpacesAndCursorPosition(textSB, 2, 6, 10)
                    }
                    textSB.length > 5 -> {
                        setSpacesAndCursorPosition(textSB, 2, 6)
                    }
                    textSB.length > 2 -> {
                        setSpacesAndCursorPosition(textSB, 2)
                    }
                }
            }
        }

        override fun afterTextChanged(s: Editable?) {
        }

        private fun setSpacesAndCursorPosition(textSB: StringBuilder, vararg ts: Int) {
            for (t in ts) // ts is an Array
                textSB.insert(t, SPACE_CHAR)
            val currentCursorPosition = getCursorPosition(exampleIdInput.selectionStart)
            exampleIdInput.setText(textSB.toString())
            exampleIdInput.setSelection(currentCursorPosition)
        }

        private fun getCursorPosition(currentCursorPosition: Int): Int {
            return if (EXAMPLE_ID_SPACE_CHAR_CURSOR_POSITIONS.contains(currentCursorPosition)) {
                currentCursorPosition + 1
            } else {
                currentCursorPosition
            }
        }

        private fun areSpacesCorrect(userInput: CharSequence?): Boolean {
            EXAMPLE_ID_SPACE_CHAR_INDEXES.forEach {
                if (userInput!!.length > it && userInput[it].toString() != SPACE_CHAR) {
                    return false
                }
            }
            return true
        }

        companion object {
            private val EXAMPLE_ID_SPACE_CHAR_INDEXES: List<Int> = listOf(2, 6, 10)
            private val EXAMPLE_ID_SPACE_CHAR_CURSOR_POSITIONS: List<Int> = EXAMPLE_ID_SPACE_CHAR_INDEXES.map { it + 1 }
            private const val SPACE_CHAR: String = " "
        }
    }

Disposition:

    <com.google.Android.material.textfield.TextInputEditText
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:digits=" 0123456789"
        Android:inputType="numberPassword"
        Android:maxLength="14"
        tools:text="Example text" />

Le résultat est:

XX XXX XXX XXX
0
Bartosz Luczak