2013-08-30 98 views
13

我試圖實現一個EditText,它將輸入限制爲只包含數字的大寫字母[A-Z0-9]。EditText上的InputFilter導致重複文本

我開始從這裏一些post.But我對三星Galaxy Tab 2得到一個問題的輸入過濾方法,但不是在模擬器或Nexus 4

問題是這樣的:

  1. 當我鍵入「A」文本顯示爲「A」其好處
  2. 現在當我鍵入「B」所以文本應該是「AB」但它給了我「AAB」 這看起來很奇怪。

總之它重複字符

以下是我正在使用此代碼工作代碼:

public class DemoFilter implements InputFilter { 

    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, 
      int dend) { 

     if (source.equals("")) { // for backspace 
      return source; 
     } 
     if (source.toString().matches("[a-zA-Z0-9 ]*")) // put your constraints 
                 // here 
     { 
      return source.toString().toUpperCase(); 
     } 
     return ""; 
    } 
} 

XML文件中的代碼:

<EditText 
    android:id="@+id/et_licence_plate_1" 
    android:layout_width="0dp" 
    android:layout_height="wrap_content" 
    android:layout_weight="3" 
    android:hint="0" 
    android:imeOptions="actionNext" 
    android:inputType="textNoSuggestions" 
    android:maxLength="3" 
    android:singleLine="true" 
    android:textSize="18px" > 
</EditText> 

我完全卡住了在這一個,所以這裏的任何幫助將不勝感激。

回答

1

InputFilters可以附加到可編輯S以約束對其可以做出的更改。 參考,它強調做,而不是它包含整個文本的變化..

遵循以下提到...

public class DemoFilter implements InputFilter { 

     public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, 
       int dend) { 

      if (source.equals("")) { // for backspace 
       return source; 
      } 
      if (source.toString().matches("[a-zA-Z0-9 ]*")) // put your constraints 
                  // here 
      { 
       char[] ch = new char[end - start]; 

       TextUtils.getChars(source, start, end, ch, 0); 

       // make the characters uppercase 
       String retChar = new String(ch).toUpperCase(); 
       return retChar; 
      } 
      return ""; 
     } 
    } 
+0

感謝我們的答覆,讓我看看這是工作或沒有? –

+0

它不能正常工作 –

+0

呵呵,我在這裏檢查了發佈的代碼,它的工作方式和預期的一樣,你是否也可以發佈你的editText的xml文件實現,在這個實現中你添加了這個DemoFilter .. – CRUSADER

0

試試這個:

class CustomInputFilter implements InputFilter { 
    StringBuilder sb = new StringBuilder(); 

    @Override 
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { 
     Log.d(TAG, "filter " + source + " " + start + " " + end + " dest " + dest + " " + dstart + " " + dend); 
     sb.setLength(0); 
     for (int i = start; i < end; i++) { 
      char c = source.charAt(i); 
      if (Character.isUpperCase(c) || Character.isDigit(c) || c == ' ') { 
       sb.append(c); 
      } else 
      if (Character.isLowerCase(c)) { 
       sb.append(Character.toUpperCase(c)); 
      } 
     } 
     return sb; 
    } 
} 

這也使過濾時過濾器()方法一次接受多個字符,例如從剪貼板粘貼文本

8

字符重複的問題來自於InputFilter的錯誤實現。而是返回null如果更換不應該改變:

@Override 
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { 
    boolean keepOriginal = true; 
    StringBuilder sb = new StringBuilder(end - start); 
    for (int i = start; i < end; i++) { 
     char c = source.charAt(i); 
     if (isCharAllowed(c)) // put your condition here 
      sb.append(c); 
     else 
      keepOriginal = false; 
    } 
    if (keepOriginal) 
     return null; 
    else { 
     if (source instanceof Spanned) { 
      SpannableString sp = new SpannableString(sb); 
      TextUtils.copySpansFrom((Spanned) source, start, end, null, sp, 0); 
      return sp; 
     } else { 
      return sb; 
     }   
    } 
} 

private boolean isCharAllowed(char c) { 
    return Character.isUpperCase(c) || Character.isDigit(c); 
} 
+0

這是正確的。請參閱InputFilter.AllCaps的實現,它將複製結果文本,如下所示。 –

+2

您可以嘗試android:inputType =「textVisiblePassword」來禁用輸入過濾器真正問題的自動完成。這不是正確的方式,但它是正常的。乾杯! –

+0

您的解決方案可行!只需要注意,這個問題只出現在Android 7上,而不出現在Android 6或Android 8上(至少對於我的應用程序來說)。 –

1

我碰到了同樣的問題,在這裏發佈仍有與自動完成鍵盤的剩餘問題的解決辦法將其固定後。一種解決方案是將inputType設置爲「visiblePassword」,但這不是減少功能嗎?

我是能夠解決的,在filter()方法返回一個非空結果時,使用呼叫

TextUtils.copySpansFrom((Spanned) source, start, newString.length(), null, newString, 0); 

此副本自動完成跨越到新的結果,解決方案和修復怪異選擇自動填充建議時的重複行爲。

+0

謝謝你,複製Spans爲我解決了它,但它有時會崩潰我的應用程序,因爲'source'並不總是'Spanned'。所以我的解決方案是: 'if(source span of spanned instance){0} {0} {0} {0} TextUtils.copySpansFrom((Spanned)source,start,newString.length(),null,newString,0); \t } return newString;' – Robyer

2

我在Android的InputFilter中發現了很多錯誤,我不確定這些錯誤是否是bug或打算如此。但絕對不符合我的要求。所以,我選擇使用TextWatcher,而不是輸入過濾

private String newStr = ""; 

myEditText.addTextChangedListener(new TextWatcher() { 
     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
      // Do nothing 
     } 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      String str = s.toString(); 
      if (str.isEmpty()) { 
       myEditText.append(newStr); 
       newStr = ""; 
      } else if (!str.equals(newStr)) { 
       // Replace the regex as per requirement 
       newStr = str.replaceAll("[^A-Z0-9]", ""); 
       myEditText.setText(""); 
      } 
     } 

     @Override 
     public void afterTextChanged(Editable s) { 
      // Do nothing 
     } 
    }); 

上面的代碼不允許用戶輸入任何特殊符號到您的EditText。只允許大寫字母數字字符。

0

以下解決方案還支持自動完成鍵盤的選項

editTextFreeNote.addTextChangedListener(new TextWatcher() { 
     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {} 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      String newStr = s.toString(); 
      newStr = newStr.replaceAll("[a-zA-Z0-9 ]*", ""); 
      if(!s.toString().equals(newStr)) { 
       editTextFreeNote.setText(newStr); 
       editTextFreeNote.setSelection(editTextFreeNote.getText().length()); 
      } 
     } 

     @Override 
     public void afterTextChanged(Editable s) {} 
    });