Android:如何在用户暂停input时向Google API发送请求?

我正在使用这个应用程序,用户可以在autoCompleteTextView中input一个位置,它会根据Google Places Api来提示位置,如下所述。

但是,我想通过只发送请求,如果用户停止input一定的时间限制应用程序发送的请求数量。 有谁知道如何做到这一点?

Solutions Collecting From Web of "Android:如何在用户暂停input时向Google API发送请求?"

类似于这个答案,但稍微更简洁,没有引入额外的状态。 您也不需要阈值检查,因为只有在实际需要过滤时才调用performFiltering

子类化AutoCompleteTextView似乎是唯一的方法,因为您不能覆盖/replace由AutoCompleteTextView添加的TextWatcher

 public class DelayAutoCompleteTextView extends AutoCompleteTextView { public DelayAutoCompleteTextView(Context context, AttributeSet attrs) { super(context, attrs); } private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { DelayAutoCompleteTextView.super.performFiltering((CharSequence) msg.obj, msg.arg1); } }; @Override protected void performFiltering(CharSequence text, int keyCode) { mHandler.removeMessages(0); mHandler.sendMessageDelayed(mHandler.obtainMessage(0, keyCode, 0, text), 750); } } 

我已经find了解决上述问题的方法,这个问题工作的很好。 我以下面的方式扩展了AutoCompleteTextView。 如果有人知道如何进一步改善这个代码,请让我知道。

 public class MyAutoCompleteTextView extends AutoCompleteTextView { // initialization int threshold; int delay = 750; Handler handler = new Handler(); Runnable run; // constructor public MyAutoCompleteTextView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void performFiltering(final CharSequence text, final int keyCode) { // get threshold threshold = this.getThreshold(); // perform filter on null to hide dropdown doFiltering(null, keyCode); // stop execution of previous handler handler.removeCallbacks(run); // creation of new runnable and prevent filtering of texts which length // does not meet threshold run = new Runnable() { public void run() { if (text.length() > threshold) { doFiltering(text, keyCode); } } }; // restart handler handler.postDelayed(run, delay); } // starts the actual filtering private void doFiltering(CharSequence text, int keyCode) { super.performFiltering(text, keyCode); } } 

您可以使用TextWatcher,并监视文本项之间的时间。 我个人不喜欢分类本机Android控件的想法(尽pipe这当然是一个有效的方法,只是不是我喜欢的方法)。

文档: http : //developer.android.com/reference/android/text/TextWatcher.html

和一个SO链接: 如何在Android中使用TextWatcher类?

类似于上面的答案,我发现我需要子类AutoCompleteTextView。 不过,因为互联网在我住的地方有点慢,我发现每次用户按下一个按键的时候删除延迟的处理程序都是一个问题。 所以基本上,如果我只在用户停止input后500ms运行filter,结果可能会花费几秒钟,这会让用户恼火。

所以相反,我不会每次都清理处理程序,并且让过滤每隔几百毫秒运行一次。 我的代码不太干净的Jan Berkel's。 我敢肯定,你可以把它清理一下,我太懒了,但是在互联网国际海事组织(IMO)缓慢的地方,性能会更好。

 public class CustomCompleteView extends AutoCompleteTextView{ Handler handler=new Handler(); Runnable r; boolean cleartogo=false; boolean pending =false; CharSequence btext; int bkeyCode; public CustomCompleteView(Context context) { super(context); // TODO Auto-generated constructor stub } public CustomCompleteView(Context context, AttributeSet attrs) { super(context,attrs); } public CustomCompleteView(Context context, AttributeSet attrs, int defStyle) { super(context,attrs,defStyle); } @Override public void performFiltering(CharSequence text, int keyCode){ if (cleartogo){ cleartogo=false; Log.d(MainActivity.DTAG,"Going to filter on " + text.toString()); pending=false; super.performFiltering(btext, bkeyCode); } else { Log.d(MainActivity.DTAG,"Filtering rejected, too soon"); btext=text; bkeyCode=keyCode; if (!pending){ if (r==null) r=new MyRunnable(this); //try{handler.removeCallbacks(r);} catch (Exception ex){}; handler.postDelayed(r, 500); pending=true;} } } private class MyRunnable implements Runnable { CustomCompleteView bc; MyRunnable(CustomCompleteView c ) { this.bc=c; } public void run() { Log.d(MainActivity.DTAG,"Special Runnable running"); cleartogo=true; bc.performFiltering(btext, bkeyCode); } } }