2016-12-28 4 views
0

私は以下の問題があります。私はいくつかのルールに従って入力テキストをフォーマットするEditTextとTextWatcherを持っています。メソッドafterTextChanged()で私はそれをフォーマットします。それから、私は文字列をフォーマットしました。そして私は、フォーマットされた値によってEditTextの古い値を置き換えたいと思います。我々は最初のオプションを使用する場合は、のEditTextは非常にゆっくりと動作し、シンボルを失い() EditTextは古いテキストをキャッシュします

  • 使用Editable.replace()
    1. 使用EditText.setText: 次は、我々は2つのオプションがあります。 しかし、2番目の方法を使用すると、編集可能では古いテキストは置き換えられず、古いテキストに新しいテキストが追加されます。

      誰かに同様の問題があったのでしょうか?

      UPD:

      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); 
        } 
    
    によって提供される方法を使用してみてください:Editable.clear()をEditable.append()を使用するか(挿入)は同様の効果

    コードを有します

    +0

    上記の理由により動作しません – Timofey

    関連する問題