2013-01-03 4 views
8

TextHatcherでGoogleのlibphonenumberのAsYouTypeFormatterを使用しようとしていますが、可能かどうかはわかりません。 EditTextフィールドから入力したテキストを書式設定し、別のEditTextで出力することはできましたが、元のEditTextフィールドを直接変更することはできませんでした(これは私が欲しいものです)。私はphoneNumberFormattingTextWatcherについて知っていますが、ユーザーは最終的には自分がどのロケールを使用しているかを選択し、それを使用するよりも(私が収集したものから)可能にします。Android AppでAsYouTypeFormatter TextWatcherを使用するにはどうすればよいですか?

クラスのトップ:

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

まず、私は私のクラスの先頭にAsYouTypeFormatterを初期化:

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

私のタブと、そのようなを作成した後、私はのEditTextボックスを作成し、フォーマットしますその中の既存の電話番号(動作している)を削除し、リスナー(現在のクラス)を添付します:

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

そして、これは私がこれらの機能の一つは、私のコードは、しかしであるべきであることを確認していない、私は私のTextWatcher機能で、現時点では持っているものである:ここでは

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

は、ログインして出力のサンプルですので、私は知っていますフォーマットが働いている:

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 

そして、ここでは、出力の画像は、(上のEditTextがphoneNumberTextと底がtestPhoneNumberTextである)である:http://imgur.com/GXwRu.png

私が知りたいことは、私は戻ってフォーマットされた出力を得るのですかあります原点にそれが入力されているように、私はEditText?私がそれをやろうとすると、奇妙なことが複製のように起こるか、それともフォーマットされていないことが示されます。 s.replace()を使ってみましたが、正しく使用しているかどうかはわかりません。これは可能ですか?ありがとう?そして、これに私のコードを変更する

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

}

aytfができなかったようだ

+1

だけPhoneNumberFormattingTextWatcherを使用しないのはなぜ( String countryCode)??? http://stackoverflow.com/a/29109236/1103584 – DiscDev

+0

minSdkVersionが必要です21 –

答えて

3

は私が一番上に新しいStringを宣言することになりました既に部分的にフォーマットされた電話番号をフォーマットするので、aytfに再送信する前にすべての非数字を削除しなければなりませんでしたか?今残っている唯一の問題は、EditTextフィールドのカーソルが今終わりではなく始めにあることですが、修正するのは問題ではありません。わーい。

EDITED CODE:ちょうどユーザーの種類としてのEditTextにユーザーが入力した電話番号をフォーマットしたいそこに他人のために

@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

+、(、)などのような特殊な文字を追加できません。どうすればよいですか? –

+0

+、(、)をこのフォーマッタで追加する予定はありません。追加する必要があります。あなたは何をしようとしているのかを明確にすることができますか? – sugarwaffle

+0

ユーザーが意図した文字で数字を入力しようとしたとします。それは受け入れるべきだと思います:) –

4

、それはPhoneNumberFormattingTextWatcherを使用する方がはるかに簡単、非常に(アンドロイドに組み込まれます)これらの冗長な答えのいずれかを試すよりも - それは一行のコードです!

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

あなたはまた、私は実際にはOPの質問に答えると思うユーザが選択した領域を渡すことができますが、それはまでは利用できなかったAPI 21:

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

これはminSdkVersion 21を宣言する必要があります。これはおそらくほとんどのプロジェクトではオプションではありません –

+2

@LouisMordaは21のminSdkVersionしか必要としませんが、リージョンを追跡することができます。より低いminSdkVersion、私はそれが利用可能であることを指摘していました。 – DiscDev

+1

いくつかの他のSOF投稿と私自身の個人的な経験によると、これは限られた数のデバイスでしか動作しません。なぜ、私は知らない。 – Nick

関連する問題