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.
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.
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)
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;
}
}
};
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, "-");
}
}
}
});
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) { }
});
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, "")
}
}
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"/>
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