2016-12-28 72 views
0

我有以下問題。我有EditText和TextWatcher根據一些規則格式化輸入文本。在方法afterTextChanged()我格式化它。然後我格式化了字符串,我想用格式化的值替換EditText的舊值。 接下來我們有兩個選擇:EditText緩存舊文本

  1. 使用EditText.setText()
  2. 使用Editable.replace()

如果我們用第一個選項,EditText上運行很慢,從而失去符號。 但是,如果我們使用第二種方法,則可編輯不會替換舊文本,而是將新文本附加到舊文本。

也許有人有類似的問題?

UPD:使用Editable.clear()然後Editable.append()或插入()具有類似的效果

代碼:

public static class LoginWatcher implements TextWatcher { 

    private EditText target; 
    private LoginFilter loginFilter = new LoginFilter(); 

    private int lastLength; 
    private boolean wasPhoneNumber = false; 

    private AsYouTypeFormatter formatter; 
    private boolean isFormattingStopped; 

    public LoginWatcher(OnLoginEnterListener onLoginInputListener, EditText target) { 
     listener = onLoginInputListener; 
     this.target = target; 
     lastLength = target.getText().length(); 
     formatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(Locale.getDefault().getCountry()); 
    } 

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

    } 

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

     if (isFormattingStopped) { 
      return; 
     } 

     if (count > 0 && hasSeparator(s, start, count)) { 
      stopFormatting(); 
     } 
    } 

    @Override 
    public void afterTextChanged(Editable s) { 
     target.removeTextChangedListener(this); 

     boolean isSymbolsChecked = loginFilter.check(s.toString()); 
     boolean isEmail = StringUtils.isEmailValid(s.toString()); 
     boolean isPhoneNumber = isPhoneNumber(s.toString()); 



     if (lastLength <= s.length()) { 
      if (isPhoneNumber && !isFormattingStopped) { 
       String formatted = reformat(s, Selection.getSelectionEnd(s)); 
       if (formatted != null) { 
        target.setText(formatted); 
        target.setSelection(target.getText().length()); 
       } 

      } else if (wasPhoneNumber) { 
       String unformatted = unFormatPhoneNumber(s.toString()); 

       target.setText(unformatted); // or s.clear(); s.append(); 
       target.setSelection(target.getText().length()); 
      } 
     } 

     lastLength = s.length(); 
     wasPhoneNumber = isPhoneNumber; 

     if (isFormattingStopped) { 
      isFormattingStopped = s.length() != 0; 
     } 

     target.addTextChangedListener(this); 
    } 

    private String unFormatPhoneNumber(String s) { 

     char[] chars = s.toCharArray(); 

     if (s.isEmpty()) { 
      return s; 
     } 

     if (chars[0] == '+') { 
      boolean isPhoneNumber = true; 
      for (int i = 1; i < chars.length; ++i) { 
       if (!Character.isDigit(chars[i])) { 
        isPhoneNumber = false; 
        break; 
       } 
      } 
      if (isPhoneNumber) { 
       return s; 
      } 
     } 

     return s.replaceAll("[\\+\\(\\)\\s\\-]+", ""); 
    } 

    private String reformat(CharSequence s, int cursor) { 
     int curIndex = cursor - 1; 
     String formatted = null; 
     formatter.clear(); 
     char lastNonSeparator = 0; 
     boolean hasCursor = false; 
     int len = s.length(); 
     for (int i = 0; i < len; i++) { 
      char c = s.charAt(i); 
      if (PhoneNumberUtils.isNonSeparator(c)) { 
       if (lastNonSeparator != 0) { 
        formatted = getFormattedNumber(lastNonSeparator, hasCursor); 
        hasCursor = false; 
       } 
       lastNonSeparator = c; 
      } 
      if (i == curIndex) { 
       hasCursor = true; 
      } 
     } 
     if (lastNonSeparator != 0) { 
      formatted = getFormattedNumber(lastNonSeparator, hasCursor); 
     } 
     return formatted; 
    } 

    private String getFormattedNumber(char lastNonSeparator, boolean hasCursor) { 
     return hasCursor ? formatter.inputDigitAndRememberPosition(lastNonSeparator) 
         : formatter.inputDigit(lastNonSeparator); 
    } 

    private boolean isPhoneNumber(String s) { 
     return !TextUtils.isEmpty(s) && Patterns.PHONE.matcher(s).matches(); 
    } 

    private boolean hasSeparator(final CharSequence s, final int start, final int count) { 
     for (int i = start; i < start + count; i++) { 
      char c = s.charAt(i); 
      if (!PhoneNumberUtils.isNonSeparator(c)) { 
       return true; 
      } 
     } 
     return false; 
    } 

    private void stopFormatting() { 
     isFormattingStopped = true; 
     formatter.clear(); 
    } 

} 
+0

分享你的代碼! –

+0

我不知道爲什麼,但我認爲你需要在可編輯實例上而不是在textField上調用setText和相關方法。 –

回答

0

嘗試使用由Editable

@Override 
    public void afterTextChanged(Editable s) { 
     target.removeTextChangedListener(this); 

     boolean isSymbolsChecked = loginFilter.check(s.toString()); 
     boolean isEmail = StringUtils.isEmailValid(s.toString()); 
     boolean isPhoneNumber = isPhoneNumber(s.toString()); 

     if (lastLength <= s.length()) { 
      if (isPhoneNumber && !isFormattingStopped) { 
       String formatted = reformat(s, Selection.getSelectionEnd(s)); 
       if (formatted != null) { 
        s.replace(0, s.length(), formatted) 
        target.setSelection(formatted.length()); 
       } 

      } else if (wasPhoneNumber) { 
       String unformatted = unFormatPhoneNumber(s.toString()); 

       s.replace(0, s.length(), formatted) 
       target.setSelection(formatted.length()); 
      } 
     } 

     lastLength = s.length(); 
     wasPhoneNumber = isPhoneNumber; 

     if (isFormattingStopped) { 
      isFormattingStopped = s.length() != 0; 
     } 

     target.addTextChangedListener(this); 
    } 
提供的方法
+0

由於上述原因,它不起作用 – Timofey