2013-08-30 26 views
13

Tôi đang cố gắng triển khai một EditText giới hạn đầu vào chỉ đối với ký tự viết hoa [A-Z0-9] với các chữ số.InputFilter trên EditText gây ra văn bản lặp lại

tôi bắt đầu với phương pháp InputFilter từ một số post.But đây tôi nhận được một vấn đề trên Samsung Galaxy Tab 2 nhưng không có trong giả lập hoặc Nexus 4.

Vấn đề là như thế này:

  1. Khi Tôi nhập "A" văn bản hiển thị là "A" tốt của nó
  2. Bây giờ, khi tôi nhập "B" để văn bản phải là "AB" nhưng nó mang lại cho tôi "AAB" trông rất lạ.

Nói tóm lại nó lặp đi lặp lại ký tự

Dưới đây là đoạn code tôi đang làm việc với mã này:

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 mã tập tin:

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

Tôi hoàn toàn bị mắc kẹt lên về điều này, vì vậy bất kỳ trợ giúp nào ở đây sẽ được đánh giá cao.

Trả lời

1

InputFilters có thể được đính kèm vào Editable S để hạn chế các thay đổi có thể được thực hiện cho họ. Tham khảo mà nó nhấn mạnh vào những thay đổi được thực hiện chứ không phải là toàn bộ văn bản đó chứa ..

Thực hiện theo như đề cập dưới đây ...

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

nhờ cho câu trả lời của chúng tôi, Hãy để tôi kiểm tra điều này đang làm việc hay không? –

+0

Không hoạt động –

+0

Huh, tôi đã kiểm tra mã được đăng ở đây và hoạt động như mong đợi, bạn cũng có thể đăng tệp triển khai tệp xml của editText mà bạn đang thêm DemoFilter này .. – CRUSADER

0

thử điều này:

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

này cũng cho phép lọc khi lọc() phương thức chấp nhận nhiều ký tự cùng một lúc, ví dụ văn bản được dán từ khay nhớ tạm

8

Sự cố sao chép ký tự đến từ việc triển khai thực hiện lỗi InputFilter. Thay vì trở về null nếu thay thế không nên thay đổi:

@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

Điều này là chính xác. Xem việc thực hiện InputFilter.AllCaps, sao chép văn bản kết quả như được hiển thị ở đây. –

+2

Bạn có thể thử android: inputType = "textVisiblePassword" để tắt tính năng tự động hoàn tất, đó là vấn đề thực sự của bộ lọc đầu vào. Nó sẽ không phải là cách thích hợp, nhưng nó chỉ hoạt động. Chúc mừng! –

+0

Giải pháp của bạn hoạt động! Chỉ cần lưu ý rằng sự cố này chỉ xuất hiện trên Android 7 chứ không phải trên Android 6 hoặc Android 8 (ít nhất là đối với ứng dụng của tôi). –

1

tôi đã chạy vào cùng một vấn đề, sau khi sửa chữa nó với các giải pháp được đăng ở đây vẫn còn là một vấn đề còn lại với bàn phím với autocomplete. Một giải pháp là đặt inputType là 'visiblePassword' nhưng đó là chức năng giảm không phải là nó?

tôi đã có thể sửa chữa các giải pháp bằng cách, khi trả về một kết quả không null trong phương pháp filter(), sử dụng các cuộc gọi

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

bản sao này tự động hoàn chỉnh nhịp vào kết quả mới và sửa chữa các lạ hành vi lặp lại khi chọn đề xuất tự động điền.

+0

Cảm ơn vì điều đó, sao chép Spans đã giải quyết nó cho tôi, nhưng nó đã bị treo ứng dụng của tôi đôi khi là 'nguồn' không phải lúc nào cũng là' Spanned'. Vì vậy, giải pháp của tôi là: 'if (nguồn instanceof Spanned) { \t TextUtils.copySpansFrom ((Spanned) source, start, newString.length(), null, newString, 0); \t } trả về newString; ' – Robyer

2

Tôi đã tìm thấy nhiều lỗi trong InputFilter của Android, tôi không chắc chắn nếu đó là lỗi hay dự định là như vậy. Nhưng chắc chắn nó không đáp ứng được yêu cầu của tôi.Vì vậy, tôi đã chọn sử dụng TextWatcher thay vì InputFilter

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

Mã trên không cho phép người dùng nhập bất kỳ biểu tượng đặc biệt nào vào EditText của bạn. Chỉ cho phép các ký tự chữ và số.

0

Các giải pháp sau đây cũng hỗ trợ các tùy chọn của một bàn phím autocomplete

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) {} 
    }); 
Các vấn đề liên quan