2013-01-03 18 views
8

Ben TextWatcher ile Google'ın libphonenumber gelen AsYouTypeFormatter kullanmaya çalışıyorum ve eğer mümkünse emin değilim ediyorum. Metni bir EditText alanından biçimlendirilmiş olarak biçimlendirdim ve başka bir EditText'de çıktı ancak orijinal EditText alanını doğrudan değiştiremedim (istediğim şey). PhoneNumberFormattingTextWatcher hakkında bilgi sahibiyim, ancak kullanıcının hangi yerel ayarları içerdiğini seçmemizi ve daha fazla denetime sahip olmanın (topladığımdan) daha fazla denetime sahip olmasını istiyoruz. sınıfınAndroid Uygulamasında AsYouTypeFormatter TextWatcher'ı nasıl kullanırım?

Üst:

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

Önce benim sınıfının en üstünde AsYouTypeFormatter başlatmak: my sekmelerin sonra

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

ve bu tür oluşturulur, ben bir EditText kutusu oluşturmak, biçimlendirmek içindeki mevcut telefon numarası (hangisi çalışır) ve dinleyiciyi (mevcut sınıf olan) ekleyin:

O zaman bu benim TextWatcher işlevlerde anda ne var, benim kod olsa olmalıdır bu işlevlerden biri emin değilim: Burada

@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) { 
} 

açmış bir örnek çıktı, bu yüzden biliyorum biçimlendirme çalışıyor:

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 

ve burada çıkışın resimdir (üst EditText phoneNumberText ve alt testPhoneNumberText ise): http://imgur.com/GXwRu.png

Ya ben geri biçimlendirilmiş çıktı nasıl alabilirim olduğunu mu merak kökenine al Yazılı olarak EditText? Bunu yapmaya çalıştığımda, garip şeyler çoğaltma gibi oluyor ya da sadece biçimlenmemiş olduğunu gösteriyor. S.replace() kullanarak denedim ama düzgün kullanıyorum emin değilim. Mümkün mü? Teşekkürler? O zaman bu benim kodu değiştirmeden

private String unformattedPhoneNumber; 

:

@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; 
    }   

}

O aytf mümkün değildi görünüyor

+1

sadece PhoneNumberFormattingTextWatcher kullanmayın Neden (Dize countryCode) ??? http://stackoverflow.com/a/29109236/1103584 – DiscDev

+0

Bu minSdkVersion 21 gerektirir –

cevap

3

Ben üst kısmındaki yeni dize ilan sona erdi zaten kısmi olarak biçimlendirilmiş telefon numaralarını biçimlendirmek için aytf'e tekrar göndermeden önce tüm basamakları çıkarmam gerekiyordu? Şimdilik kalan tek sorun, EditText alanındaki imlecin şimdiki zamanın başlangıcında başlamasıdır, fakat bu düzeltmek için bir problem olmamalıdır. Yuppi.

DÜZENLENECEK KODU: Sadece kullanıcı yazarken bir EditText bir kullanıcı tarafından girilen telefon numarasını biçimlendirmek istediğiniz orada Diğerleri için

@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

Özel chara +, (,) etc… ekleyemiyorum ne yapmalıyım? –

+0

Bu biçimlendiriciyle +, (,) eklemiyor olmanız, sizin için eklemesi gerekir. Ne yapmaya çalıştığını açıklayabilir misin? – sugarwaffle

+0

Kullanıcı, sayıları istenen karakterlerle girmeyi denediğini varsayalım, bunu kabul etmeliyim :) –

4

, bu PhoneNumberFormattingTextWatcher kullanımı çok daha kolaydır, çok (Android'e yerleşik bulunuyor) Bu ayrıntılı cevaplardan herhangi birini denemek - ve bir KOD HATTI!

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

Ayrıca ben aslında OP'ın soruya cevap olacağını düşünüyorum kullanıcının seçtiği bölgeyi geçebilir, ama bu kadar mevcut değildi API 21:

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

Bu muhtemelen minSdkVersion 21 ilan etmenizi gerektirir, bu muhtemelen şu anda çoğu proje için bir seçenek değildir –

+2

@LouisMorda sadece bölgeyi geçmek için gerekli minSdkVersion 21 - bölgeyi diğer yollarla (projemde yaptığım gibi) takip edebilirsiniz daha düşük bir minSdkVersion, sadece kullanılabilir olduğunu işaret ediyordum. – DiscDev

+1

Diğer birçok SOF yazısının ve kendi kişisel deneyimimin başına, bu yalnızca sınırlı sayıda cihazda çalışır. Neden, bilmiyorum. – Nick