1

在 AutoCompleteTextView 中,我想在用户输入暂停 1 秒后显示自动完成列表。我尝试使用处理程序

handler.postDelayed( new Runnable() {

            @Override
            public void run() {

                // TODO Auto-generated method stub
                if ( text.length() >= 3 ) {
                    // do something                     

                } else if ( text.length() == 0 ) {
                    // do something

                }
            }

        }, 1000 );

此代码是 onTextChanged 的​​一部分。所以它发生的情况是,只要在那一刻有文本更改 postDelayed 被调用,内部代码将在一秒钟后被调用。那么我怎样才能防止这种情况发生,所以只有当用户在输入时有 1 秒的暂停时才会调用内部代码。

例如:如果我输入 Ind(暂停 1 秒),则应该执行内部代码。但是我输入 India 然后内部代码不应该为 Ind, Indi, India 执行。需要你的建议。

4

4 回答 4

2

创建两个包含时间戳的静态变量。
lastTimeStampcurrentTimeStamp然后你可以做这样的事情:

        @Override
        public void run() {
            if (currentTimeStamp - lastTimeStamp > 1000) {
               // TODO Auto-generated method stub
               if ( text.length() >= 3 ) {
                  // do something                     

               } else if ( text.length() == 0 ) {
                     // do something

               }
            }
        }

新的方法:

在 onTextChanged 方法的开头,将当前 TimeStamp 放入类变量中。
此后在 onTextChanged 中创建一个 AsyncTask,这只是 Thread.sleep(1000)在 doInBackground 方法中执行的操作。
然后您在 postExcute 方法中创建一个 if 语句,检查类变量中的 TimeStamp 与当前 TimeStamp 之间的差异是否大于 1000 发布您的处理程序。

于 2013-02-25T12:30:55.653 回答
1

我只是站在同样的问题上。
我正在调用 Google 地理编码建议 API onTextChanged(),这导致了很多问题。用户键入会导致大量 API 请求,其中大多数不是必需的,并且会耗尽 API(成本)并降低用户从应用程序获得的体验。

我在这里考虑了解决方案,但最后我不喜欢其中的任何一个,它们看起来不干净或像黑客一样。
我不想进一步调用 UI 来获取 View 的当前值(再次)或检查系统时间。

最初的问题实际上已经解决了这个问题,它只是在用户键入时导致多个可运行文件处于活动状态。
所以问题应该是:“如何在它引起麻烦之前删除我的匿名可运行文件?”

您所要做的就是使用原始方法(使用匿名可运行的延迟调用),并且每当调用 onTextChanged 函数时,您都可以删除任何以前的可运行。
您还可以扩展代码并检查值是否真的发生了变化(例如使用全局先前值字符串),因此如果用户输入一个字符并再次删除它,则可运行对象不会被杀死。

因此,您需要做的就是: 1. 将 Handler 设为类的变量,而不是在 onTextChanged 中创建它。
2. 在 onTextChanged 开始时,从处理程序中删除可运行对象

这是一个功能齐全的示例:

    Handler onchangeHandler =  new Handler();
    String last_onTextChanged=""; // may speed up some cases of user input, can be removed
    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i2, int i3)
    {
        final String value = charSequence.toString();
        if (value.length() < 3) {autoCompleteAdapter.clear();return;} // threshold of 3 chars

        if (!last_onTextChanged.equals(value))
            onchangeHandler.removeCallbacksAndMessages(null);
        else
            return;
    last_onTextChanged=value;
    onchangeHandler.postDelayed(new Runnable()
    {
        @Override
        public void run()
        {
            // RUN CODE HERE, fill your autoCompleteAdapter etc.
        }
    },800);

}
于 2014-04-05T16:07:45.770 回答
0

有2个选项:

  1. 当您要运行下一个任务时,使用 Timer 并在以前的任务上调用 cancel()。

  2. 扩展 Runnable 并为此自动完成传入一个字符串。如果此字符串不等于视图中的当前字符串(这意味着用户更改了字符串),则不应显示自动完成。

代码示例:

abstract class MyRunnable {
    private String str;

    public MyRunnable(String str) {
        this.str = str;
    }
}


...

handler.postDelayed(new MyRunnable(currentViewStr) {

    @Override
    public void run() {
        if (currentViewStr.equals(str)) {
            // show autocompletion
        }
    }
}, 1000);
于 2013-02-25T12:55:55.853 回答
0

您也可以Runnable先取消消息队列中的前一个消息onTextChanged()

于 2013-02-25T13:23:07.243 回答