2012-10-09 30 views
18

Làm thế nào tôi có thể tránh điều đó một dòng mã như:Làm thế nào tôi có thể tránh thực hiện OnTextChanged trong Android của EditText

((EditText) findViewById(R.id.MyEditText)).setText("Hello"); 

sẽ gây ra một sự kiện ở đây:

((EditText) findViewById(R.id.MyEditText)).addTextChangedListener(new TextWatcher() { 
@Override 
public void onTextChanged(CharSequence s, int start, 
    int before, int count) { 
// HERE 
} 

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

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

Tôi muốn biết nếu có bất kỳ cách nào để ngăn chặn việc thực hiện onTextChanged như tôi nhận thấy trong trường hợp chọn kết quả xổ xuống của AutoCompleteTextView (không có onTextChanged được thực hiện!).

Tôi không tìm kiếm cách giải quyết như "nếu chào không làm gì cả" ...

+11

Đặt văn bản sẽ kích hoạt trình nghe đó. Một cách đơn giản là có một tham chiếu đến 'TextWatcher', loại bỏ trình lắng nghe trước khi thiết lập văn bản (với' removeTextChangedListener (watcher) '), thiết lập văn bản, bật lại trình nghe (với' addTextChangedListener (watcher) '). Bạn có thể có điều này trong một phương pháp để thuận tiện nếu bạn làm điều đó nhiều hơn một vài lần. – Luksprog

+0

bản sao có thể có của [Android: Làm thế nào tôi có thể thay đổi văn bản EditText mà không kích hoạt Trình xem văn bản mà tôi có trên đó?] (Http://stackoverflow.com/questions/9385081/android-how-can-i-change-the- edittext-text-without-triggering-the-text-watcher) – danpetruk

+0

Ví dụ về cùng một câu hỏi được giải quyết để cập nhật trên hộp kiểm với người nghe http://stackoverflow.com/a/15523518/2162226 – gnB

Trả lời

22

The Source cho AutoCompleteTextView cho thấy rằng họ thiết lập một boolean để nói rằng văn bản đã được thay thế bằng việc hoàn khối

  mBlockCompletion = true; 
     replaceText(convertSelectionToString(selectedItem)); 
     mBlockCompletion = false;  

Đây là tốt một cách như nào để đạt được những gì bạn muốn làm. Các TextWatcher sau đó kiểm tra để xem liệu setText đã đi qua một hoàn thành và lợi nhuận ra khỏi phương pháp

void doBeforeTextChanged() { 
    if (mBlockCompletion) return; 

Thêm và loại bỏ các TextWatcher sẽ nhiều thời gian tiêu tốn cho việc áp dụng

1

Tôi không nghĩ rằng có một cách dễ dàng để vô hiệu hóa người nghe, nhưng bạn có thể khắc phục nó bằng cách:

  • Xóa TextWatcher trước khi bạn đặt văn bản và thêm lại sau.
  • Hoặc đặt cờ boolean trước khi bạn đặt văn bản, thông báo cho số TextWatcher bỏ qua nó.

Ví dụ:

boolean ignoreNextTextChange = true; 
((EditText) findViewById(R.id.MyEditText)).setText("Hello"); 

Và trong bạn TextWatcher:

new TextWatcher() { 
    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
     /* 
     If the flag is set to ignore the next text change, 
     reset the flag, and return without doing anything. 
     */ 
     if (ignoreNextTextChange){ 
      ignoreNextTextChange = false; 
      return; 
     } 
    } 

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

    } 

    @Override 
    public void afterTextChanged(Editable s) { 

    } 
}); 

Đó là một chút hacky, nhưng nó phải làm việc :)

+0

Sẽ quay lại ngăn chặn việc thực hiện trước và sau văn bản thay đổi quá, hoặc bạn sẽ cần một kiểm tra boolean có? – Menasheh

0

Chỉ có hai cách tôi có thể nhìn thấy

  • bạn kiểm tra trong phạm vi người nghe
  • bạn thêm/xóa người nghe theo cer điều kiện tain

Cách đầu tiên là giải pháp không mong muốn cho bạn Tôi sợ bạn đã làm việc xung quanh theo cách thứ hai.

1

Một cách khác để đạt được điều này sẽ là sử dụng setOnKeyListener.

Điều này sẽ chỉ kích hoạt khi người dùng nhấn phím thay vì bất cứ khi nào EditText được thay đổi bởi người dùng HOẶC theo lập trình.

myEditText.setOnKeyListener(new EditText.OnKeyListener() { 
    public boolean onKey(View v, int keyCode, KeyEvent event) { 
     switch(event.getAction()) { 
      case KeyEvent.ACTION_DOWN: 
       // beforeTextChanged 
       break;  
      case KeyEvent.ACTION_UP: 
       // afterTextChanged 
       break; 
     } 
     return false; 
    } 
}); 
5

Tôi đã gặp phải vấn đề tương tự. Tôi đã tìm hiểu xem Chế độ xem nào hiện có tiêu điểm để phân biệt giữa các sự kiện do người dùng kích hoạt và chương trình.

EditText myEditText = ((EditText) findViewById(R.id.myEditText)); 

myEditText.addTextChangedListener(new TextWatcher() 
{ 
    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) 
    { 
     if(getCurrentFocus() == myEditText) 
     { 
      // is only executed if the EditText was directly changed by the user 
     } 
    } 

    //... 
}); 
0

Hoặc bạn chỉ có thể sử dụng để phân biệt giữa mEditText.hasFocus() Văn bản do con người thay đổi hoặc chương trình thay đổi, điều này hoạt động tốt đối với tôi:

@Override 
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { 
    if (mEditText.hasFocus()) { 
     // Do whatever 
    } 
} 

Hope this helps!

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