How to avoid multiple triggers on EditText while u

2019-02-01 21:11发布

I use the following code to perform search when user types in an EditText :

EditText queryView = (EditText) findViewById(R.id.querybox);
queryView.addTextChangedListener(new TextWatcher() {
  @Override
  public void afterTextChanged(Editable s) {
    triggerSearch(s.toString()); 
  }
  @Override
  public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  }
  @Override
  public void onTextChanged(CharSequence s, int start, int before, int count) {
  }
});

However, this triggers multiple times when the user is typing a word. That is if the user is typing "hello", this code will trigger 5 times with values ("h", "he" , "hel", "hell", "hello"). Normally, this would be fine but the triggered search is expensive and I don't want to waste resources on intermediate searches that are of no great use. What I want is either a listener that triggers only a certain threshold after the user starts typing, or some kind of framework, that waits in the listener before calling triggerSearch, and if another event is triggered before that wait, cancels itself.

4条回答
孤傲高冷的网名
2楼-- · 2019-02-01 21:48

Since couldn't find an appropriate event interface, tried triggering a delayed search. The code is actually pretty simple and robust.

private final int TRIGGER_SERACH = 1;
// Where did 1000 come from? It's arbitrary, since I can't find average android typing speed.
private final long SEARCH_TRIGGER_DELAY_IN_MS = 1000;

  private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
      if (msg.what == TRIGGER_SERACH) {
        triggerSearch();
      }
    }
  };

 queryView.addTextChangedListener(new TextWatcher() {

   @Override
   public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {

   }

   @Override
   public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {

   }

   @Override
   public void afterTextChanged(Editable s) {
    handler.removeMessages(TRIGGER_SERACH);
    handler.sendEmptyMessageDelayed(TRIGGER_SERACH, SEARCH_TRIGGER_DELAY_IN_MS);
   });
查看更多
Animai°情兽
3楼-- · 2019-02-01 21:55

One solution would be to not execute your triggered search immediately but after some interval, say 100ms, has passed since the onTextChanged method gets called. Additionally reset this interval each time text is typed.

This way the triggered search doesn't get called while the user is typing.

查看更多
走好不送
4楼-- · 2019-02-01 21:55

To wait in the listener before calling triggerSearch; test the length of Editable s.

if(s.length() > THRESHOLD)

查看更多
男人必须洒脱
5楼-- · 2019-02-01 21:59

If you don't want to trigger the search on every button pressed, then you need to know when the user is done. I would avoid complex ideas of attempting to figure out when the user is done typing. It will lead to the user being confused as to when the search occurs.

Simple answer then is put a "done" button and apply an onClickListener on the button and execute your search there.

Easiest code: in xml

<Button
android:onClick="onDoneClicked"
... the rest of your button layout
/>

in java:

@Override
public void onDoneClicked(View view){
EditText queryView = (EditText) findViewById(R.id.querybox);
triggerSearch(queryView.toString());
}
查看更多
登录 后发表回答