5

Trong ứng dụng Android của tôi, tôi cần triển khai giao diện TextWatcher để triển khai onTextChanged. Vấn đề tôi có là, tôi muốn cập nhật cùng một EditText Với ​​một số chuỗi phụ. Khi tôi cố gắng làm điều này chương trình chấm dứt.Làm cách nào để cập nhật cùng một EditText bằng cách sử dụng TextWatcher?

final EditText ET = (EditText) findViewById(R.id.editText1); 
ET.addTextChangedListener(new TextWatcher() { 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) 
     { 
      try 
      { 
       ET.setText("***"+ s.toString()); 
       ET.setSelection(s.length()); 
      } 
      catch(Exception e) 
      { 
       Log.v("State", e.getMessage()); 
      } 
     } 

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

     } 

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

Chương trình của tôi chấm dứt và thậm chí tôi cố gắng nắm bắt ngoại lệ như trong mã của tôi mà nó vẫn chấm dứt. Có ai có bất kỳ ý tưởng nào tại sao điều này xảy ra và làm cách nào tôi có thể đạt được điều này? Cảm ơn.

+1

'Khi tôi cố gắng làm chương trình này terminates.' rằng về cơ bản có nghĩa là bạn nên cung cấp dấu vết ngăn xếp có thể được tìm thấy trong LogCat. Điều đó sẽ giúp chúng tôi rất nhiều! – WarrenFaith

Trả lời

8

Nội dung của TextViewkhông thể chỉnh sửa trên sự kiện onTextChanged.

Thay vào đó, bạn cần xử lý sự kiện afterTextChanged để có thể thực hiện thay đổi đối với văn bản.

Để biết thêm triệt để giải thích see: Android TextWatcher.afterTextChanged vs TextWatcher.onTextChanged


Note: Lỗi onTextChanged

Obvioulsy, bạn đang gây ra một vòng lặp vô tận bằng cách liên tục thay đổi văn bản trên afterTextChanged sự kiện.

Từ the ref:

public void trừu tượng afterTextChanged (Editable s)
Phương pháp này được gọi là để thông báo cho bạn rằng, ở đâu đó trong s, các văn bản đã được thay đổi. Việc thực hiện các thay đổi thêm cho s từ cuộc gọi này là hợp pháp, nhưng hãy cẩn thận không để bạn vào vòng lặp vô hạn, vì bất kỳ thay đổi nào bạn thực hiện sẽ khiến phương thức này được gọi lại đệ quy. ...

  • Đề xuất 1: nếu bạn có thể, kiểm tra xem sđã những gì bạn muốn khi sự kiện được kích hoạt.

    @Override 
    public void afterTextChanged(Editable s) 
    {  
        if(!s.equalsIngoreCase("smth defined previously")) 
         s = "smth defined previously";    
    } 
    
  • Đề xuất 2: nếu bạn cần để làm công cụ phức tạp hơn (định dạng, xác nhận), bạn có thể có thể sử dụng một phương pháp synchronized như trong this post.

Note 2: Định dạng đầu vào bị ẩn một phần với n sao cho đến cha mới nhất rs (**** bốn)

Bạn có thể sử dụng một cái gì đó như thế này trong gợi ý 1:

@Override 
    public void afterTextChanged(Editable s) 
    {  
     String sText = ET.getText().toString() 

     if(!isFormatted(sText)) 
      s = format(sText);    
    } 
    bool isFormatted(String s) 
    { 
    //check if s is already formatted 
    } 

    string format(String s) 
    { 
     //format s & return 
    } 
+0

HI Zorkun, tôi đã thử thêm cùng một mã trong sự kiện afterTextChanged (Editable s) ... Vẫn còn nó chấm dứt ... Bạn có biết cách nào khác thay thế để làm điều này?Cảm ơn – JibW

+0

Các s có thể chỉnh sửa trong afterTextChanged (Editable s). Nhưng vẫn không thể gán cho EditText. – JibW

+0

Đúng vậy. Nó gây ra một vòng lặp vô tận bằng cách liên tục thay đổi văn bản trên sự kiện afterTextChanged. Vấn đề là, tôi muốn ẩn các chữ cái đầu tiên trong EditText, với một số ký tự dưới dạng * và chỉ cho phép 4 ký tự mới hiển thị ... – JibW

1

Bổ sung Zortkun's answer (nơi mã ví dụ được khá bị hỏng), đây là cách bạn muốn sử dụng afterTextChanged() để cập nhật cùng EditText:

editText.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) {  
    } 

    @Override 
    public void afterTextChanged(Editable editable) {   
     if (!editable.toString().startsWith("***")) { 
      editable.insert(0, "***"); 
     }   
    } 
}); 

Làm quen với giao diện Editable để tìm hiểu về các hoạt động khác ngoài insert().

Lưu ý rằng dễ dàng kết thúc trong một vòng lặp vô hạn (những thay đổi bạn kích hoạt lại afterTextChanged()), vì vậy thông thường bạn sẽ thực hiện các thay đổi trong điều kiện nếu, như trên.

Như afterTextChanged()javadocs nói:

Nó là hợp pháp để thực hiện thay đổi hơn nữa để s từ callback này, nhưng cẩn thận không để có được cho mình vào một vòng lặp vô hạn, bởi vì bất kỳ thay đổi mà bạn thực hiện sẽ gây ra điều này phương thức được gọi lại đệ quy.

0

câu trả lời muộn, nếu ai đó tìm kiếm đây là cách tôi đã làm.

  • bộ addTextChangedListener ban đầu
  • trong một trong những cuộc gọi trở lại (nói OnTextChanged()) loại bỏ addTextChangedListener
  • Vẫn quan tâm trong việc tiếp nhận thông tin cập nhật thêm nó trở lại.

đây là mã.

editText.addTextChangedListener(new TextWatcher() { 
     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
      Log.d("log", "before"); 
     } 

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

      Log.d("log", "after"); 
      editText.removeTextChangedListener(this); 

      ediText.setText("text you wanted to put"); 

      editText.addTextChangedListener(this); 

     } 

     @Override 
     public void afterTextChanged(Editable s) { 


     } 
    }); 
0

Dưới đây là một đoạn mà làm việc cho tôi

etPhoneNumber.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) {} 

     @Override 
     public void afterTextChanged(Editable s) { 
      if (!s.toString().equals(Utils.getFormattedNumber(s.toString()))) { 
       s.replace(0, s.length(), Utils.getFormattedNumber(s.toString())); 
      } 
     } 
    }); 

nơi Utils.getFormattedPhoneNumber() là phương pháp của bạn trả lại một số định dạng

Các vấn đề liên quan