2013-01-03 18 views
8

Sto cercando di utilizzare AsYouTypeFormatter dal libphonenumber di Google con TextWatcher e non sono sicuro che sia possibile. Sono stato in grado di formattare il testo digitato da un campo EditText e di inviarlo in un altro EditText ma non in grado di modificare direttamente il campo EditText originale (che è quello che voglio). So di phoneNumberFormattingTextWatcher ma vogliamo che l'utente sia in grado di selezionare le impostazioni internazionali in cui si trovano e avere più controllo di quello consentito (da ciò che ho raccolto).Come utilizzare AsYouTypeFormatter TextWatcher nell'app per Android?

superiore della classe:

private View phoneNumberView; 
private EditText phoneNumberText; 
private String formattedPhoneNumber; 
private boolean isInAfterTextChanged; 
private AsYouTypeFormatter aytf; 

Per prima cosa ho inizializzare l'AsYouTypeFormatter in cima alla mia classe:

aytf = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(Locale.getDefault().getCountry()); 

Dopo le mie schede e come vengono creati, creo una scatola EditText, formattare il numero di telefono esistente all'interno di esso (che funziona) e collegare il listener (che è la classe corrente):

phoneNumberView = inflater.inflate(R.layout.phone_number_setting, null); 
phoneNumberText = (EditText) phoneNumberView.findViewById(R.id.dirty_phone_number); 
phoneNumberText.setText(dirtyPhoneNumber); 
for (int i = 0; i < dirtyPhoneNumber.length(); i++){ 
    phoneNumberText.setText(aytf.inputDigit(dirtyPhoneNumber.charAt(i))); 
} 
aytf.clear(); 
phoneNumberText.setText(dirtyPhoneNumber); 
phoneNumberText.addTextChangedListener(this); 

Allora questo è quello che ho in questo momento nelle mie funzioni TextWatcher, io non sono sicuro che uno di queste funzioni mio codice dovrebbe essere in se:

@Override 
public void afterTextChanged(Editable s) { 
    if (!isInAfterTextChanged) { 
      isInAfterTextChanged = true; 

      if(s.length() > 0){ 
       Log.v("AsYouTypeFormatter - source", s.toString()); 
       for(int i = 0; i < s.length(); i++){ 
        formattedPhoneNumber = aytf.inputDigit(s.charAt(i)); 
        Log.v("AsYouTypeFormatter - formatted", formattedPhoneNumber); 

       } 
       Log.v("AsYouTypeFormatter - source after loop", s.toString()); 
      //The formatted output shows properly in this EditText but not when I try to put it back into the original one (phoneNumberText) 
       EditText testPhoneNumberText = (EditText) phoneNumberView.findViewById(R.id.testPhoneNumberText); 
       testPhoneNumberText.setText(formattedPhoneNumber); 
       aytf.clear(); 
      } 

      formattedPhoneNumber = null; 
      isInAfterTextChanged = false; 
     }   

} 

@Override 
public void beforeTextChanged(CharSequence s, int start, int count, 
     int after) { 
} 

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

Ecco un esempio di output connesso, quindi so la formattazione sta lavorando:

01-03 10:55:02.838: V/AsYouTypeFormatter - source(27114): 15552451234 
01-03 10:55:02.838: V/AsYouTypeFormatter - formatted(27114): 1 
01-03 10:55:02.838: V/AsYouTypeFormatter - formatted(27114): 15 
01-03 10:55:02.838: V/AsYouTypeFormatter - formatted(27114): 1 55 
01-03 10:55:02.838: V/AsYouTypeFormatter - formatted(27114): 1 555 
01-03 10:55:02.838: V/AsYouTypeFormatter - formatted(27114): 1 555-2 
01-03 10:55:02.838: V/AsYouTypeFormatter - formatted(27114): 1 555-24 
01-03 10:55:02.850: V/AsYouTypeFormatter - formatted(27114): 1 555-245 
01-03 10:55:02.850: V/AsYouTypeFormatter - formatted(27114): 1 555-245-1 
01-03 10:55:02.850: V/AsYouTypeFormatter - formatted(27114): 1 555-245-12 
01-03 10:55:02.850: V/AsYouTypeFormatter - formatted(27114): 1 555-245-123 
01-03 10:55:02.850: V/AsYouTypeFormatter - formatted(27114): 1 555-245-1234 
01-03 10:55:02.850: V/AsYouTypeFormatter - source after loop(27114): 15552451234 

ed ecco l'immagine della produzione (in alto EditText è phoneNumberText e in basso è testPhoneNumberText): http://imgur.com/GXwRu.png

Quello che voglio sapere è come faccio a ottenere l'output formattato indietro nell'origine al EditText mentre viene digitato? Quando provo a farlo, le cose strane capita come una duplicazione o lo mostra semplicemente non formattato. Ho provato a utilizzare s.replace() ma non sono sicuro che lo sto usando correttamente. È possibile? Grazie?

+1

Perché non usare PhoneNumberFormattingTextWatcher (Stringa countryCode) ??? http://stackoverflow.com/a/29109236/1103584 – DiscDev

+0

Ciò richiede minSdkVersion 21 –

risposta

3

ho finito per dichiarare una nuova stringa in alto:

private String unformattedPhoneNumber; 

Poi cambiare il mio codice a questo:

@Override 
public void afterTextChanged(Editable s) { 
if (!isInAfterTextChanged) { 
     isInAfterTextChanged = true; 

     if(s.length() > 0){ 
      Log.v("AsYouTypeFormatter - source", s.toString()); 
      unformattedPhoneNumber = s.toString().replaceAll("[^\\d.]", ""); 
      for(int i = 0; i < unformattedPhoneNumber.length(); i++){ 
       formattedPhoneNumber = aytf.inputDigit(unformattedPhoneNumber.charAt(i)); 
       Log.v("AsYouTypeFormatter - formatted", formattedPhoneNumber); 

      } 
      Log.v("AsYouTypeFormatter - source after loop", s.toString()); 

      phoneNumberText.setText(formattedPhoneNumber); 

      aytf.clear(); 
     } 

     formattedPhoneNumber = null; 
     isInAfterTextChanged = false; 
    }   

}

Sembra che l'aytf non era in grado per formattare i numeri di telefono già parzialmente formattati, quindi ho dovuto rimuovere tutte le cifre non prima di inviarlo nuovamente a aytf? L'unico problema rimasto ora è che il cursore nel campo EditText è all'inizio anziché alla fine, ma non dovrebbe essere un problema da risolvere. Sìì.

codice modificato:

@Override 
public void afterTextChanged(Editable s) { 
    if (!isInAfterTextChanged) { 
     isInAfterTextChanged = true; 
     phoneNumberText.setText(pnu.updateNationalNumber(s.toString())); 
     phoneNumberText.setSelection(this.phoneNumberText.getText().length()); 
     isInAfterTextChanged = false; 
    } 
} 

/** 
* Updates the national number based on the param s 
* Takes all formatting out of param s and then reformats the number 
* using the AsYouTypeFormatter for libphonenumber and based upon 
* the region code 
* 
* @param s The formatted value to be used to update the national number 
* @return String The new formatted national number 
*/ 
public String updateNationalNumber(String s){ 
    //Instantiate the as you type formatter with the current region (US or UK) 
    aytf = phoneUtil.getAsYouTypeFormatter(this.currentRegionCode.getCountryCode()); 
    String fNationalNumber = null; 

    //Format the string 
    if(s.length() > 0){ 
     String digitString = null; 
     //If it's in the US remove all leading 1s (international code) 
     if(this.currentRegionCode == RegionCode.US){ 
      digitString = new String(s.replaceAll("(^[1?])|([^\\d.])", "")); 
     } 
     //If it's in the UK remove all leading 44s (international code) 
     else if (this.currentRegionCode == RegionCode.GB){ 
      digitString = new String(s.replaceAll("(^[4?]{2})|([^\\d.])", "")); 
     } 
     if(digitString != null){ 
      //RE input all of the digits into the formatter 
      for(int i = 0; i < digitString.length(); i++){ 
       fNationalNumber = aytf.inputDigit(digitString.charAt(i)); 
      } 
     } 

     //Clear the formatter for the next round of input 
     aytf.clear(); 

     //Try to update the phone number with the formatted number 
     try { 
      phoneUtil.parse(fNationalNumber, this.currentRegionCode.getCountryCode(), this.uPhoneNumber); 
     //Rejects if the number isn't in an acceptable format for the region code given etc. 
     } catch (NumberParseException e) { 
      System.err.println("NumberParseException was thrown: " + e.toString()); 
     } 
    } 
    //Return the formatted phone number 
    return fNationalNumber; 
} 
+0

Non posso aggiungere il chara speciale come +, (,) ecc ... cosa fare? –

+0

Non dovresti aggiungere +, (,) con questo formattatore, dovrebbe aggiungerlo per te. Potresti chiarire cosa stai cercando di fare? – sugarwaffle

+0

Supponiamo che l'utente provi ad inserire i numeri con i caratteri previsti, penso che dovrebbe accettarlo :) –

4

Per gli altri là fuori che vogliono solo per formattare un numero di telefono inserito dall'utente in un EditText come i tipi di utenti, è molto, molto più facile da usare PhoneNumberFormattingTextWatcher (integrata in Android) di tentare una di queste risposte verbose - ed è UNA LINEA DI CODICE!

//Add a special listener for this instance that will format phone numbers on the fly. 
this.editText.addTextChangedListener(new PhoneNumberFormattingTextWatcher()); 

È anche possibile passare la regione l'utente ha selezionato, che credo sarebbe effettivamente rispondere alla domanda del PO, ma non era disponibile fino API 21:

//This version takes a country code! 
this.editText.addTextChangedListener(new PhoneNumberFormattingTextWatcher("US")); 
+0

Ciò richiede di dichiarare minSdkVersion 21, che probabilmente non è un'opzione per la maggior parte dei progetti al momento –

+2

@LouisMorda solo passando la regione richiesta minSdkVersion di 21 - puoi tenere traccia della regione in altri modi (come faccio nel mio progetto) per supportare una versione minSdk inferiore, stavo solo sottolineando che è disponibile. – DiscDev

+1

Per diversi altri post SOF e la mia esperienza personale, funziona solo su un numero limitato di dispositivi. Perché, non lo so. – Nick