Java Android:AutoCompleteTextView和过滤器-输入延迟-为什么?

Java Android:AutoCompleteTextView和过滤器-输入延迟-为什么?,java,android,android-arrayadapter,autocompletetextview,android-filterable,Java,Android,Android Arrayadapter,Autocompletetextview,Android Filterable,好了,伙计们,这让我发疯了,我在互联网上找不到解决办法 我做了一个新的Eclipse项目,并将此代码粘贴到: 它可以工作,但如果我输入或删除字符,在键入它们时通常会有延迟(短暂冻结),建议下拉列表会消失并再次出现。 就我的理解而言,过滤本身是异步完成的,因此是从后台线程开始的,那么为什么短线程会冻结呢? 我的目标是像Google Play Store一样拥有一个无冻结的AutoCompleteTextView。 你们有什么建议/解决方法来实现这一点吗?你们必须使用以下库文件。你们必须在Auto

好了,伙计们,这让我发疯了,我在互联网上找不到解决办法
我做了一个新的Eclipse项目,并将此代码粘贴到:



它可以工作,但如果我输入或删除字符,在键入它们时通常会有延迟(短暂冻结),建议下拉列表会消失并再次出现。
就我的理解而言,过滤本身是异步完成的,因此是从后台线程开始的,那么为什么短线程会冻结呢?

我的目标是像Google Play Store一样拥有一个无冻结的AutoCompleteTextView。

你们有什么建议/解决方法来实现这一点吗?

你们必须使用以下库文件。你们必须在AutoCompletetextView上调用
addTextChangeListener(Listener)
。在
PostTextChanged(可编辑的)
中,您必须提到需要执行的功能

/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.text;

/**
 * When an object of a type is attached to an Editable, its methods will
 * be called when the text is changed.
 */
public interface TextWatcher extends NoCopySpan {
    /**
     * This method is called to notify you that, within <code>s</code>,
     * the <code>count</code> characters beginning at <code>start</code>
     * are about to be replaced by new text with length <code>after</code>.
     * It is an error to attempt to make changes to <code>s</code> from
     * this callback.
     */
    public void beforeTextChanged(CharSequence s, int start,
                                  int count, int after);
    /**
     * This method is called to notify you that, within <code>s</code>,
     * the <code>count</code> characters beginning at <code>start</code>
     * have just replaced old text that had length <code>before</code>.
     * It is an error to attempt to make changes to <code>s</code> from
     * this callback.
     */
    public void onTextChanged(CharSequence s, int start, int before, int count);

    /**
     * This method is called to notify you that, somewhere within
     * <code>s</code>, the text has been changed.
     * It is legitimate to make further changes to <code>s</code> from
     * this callback, but be careful not to get yourself into an infinite
     * loop, because any changes you make will cause this method to be
     * called again recursively.
     * (You are not told where the change took place because other
     * afterTextChanged() methods may already have made other changes
     * and invalidated the offsets.  But if you need to know here,
     * you can use {@link Spannable#setSpan} in {@link #onTextChanged}
     * to mark your place and then look up from here where the span
     * ended up.
     */
    public void afterTextChanged(Editable s);
}

我通过放置以下代码行解决了这个问题(请参见注释):

            @Override
            protected FilterResults performFiltering(CharSequence constraint)
            {
                FilterResults filterResults = new FilterResults();

                // ADDED CODE: TO FIX ERROR "The content of the adapter has changed but ListView did not receive a notification":
                ArrayList <String> resultListTemp = new ArrayList <String> ();

                if (constraint != null)
                {
                    // ADDED CODE: TO STOP TYPING DELAY & TO FIX ERROR: "The content of adapter has changed but ListView did not receive a notification"
                    if (conn != null)
                    {
                        conn.disconnect();
                    }

                    // CHANGED CODE: TO FIX ERROR "The content of the adapter has changed but ListView did not receive a notification":
                    resultListTemp.addAll(autocomplete(constraint.toString()));

                    filterResults.values = resultListTemp;
                    filterResults.count = resultListTemp.size();
                }
                return filterResults;
            }


            @Override
            protected void publishResults(CharSequence constraint, FilterResults results)
            {
                // ADDED CODE: TO FIX ERROR "The content of the adapter has changed but ListView did not receive a notification":
                resultList = (ArrayList <String>) results.values;

                if (results != null && results.count > 0)
                {
                    notifyDataSetChanged();
                }
                else
                {
                    notifyDataSetInvalidated();
                }
            }


            private ArrayList<String> autocomplete(String input)
            {
                // CHANGED CODE: TO FIX ERROR "The content of the adapter has changed but ListView did not receive a notification":
                ArrayList<String> resultList = new ArrayList <String> ();
                .....
                .....
            }
@覆盖
受保护的筛选器结果性能筛选(CharSequence约束)
{
FilterResults FilterResults=新的FilterResults();
//添加代码:修复错误“适配器的内容已更改,但ListView未收到通知”:
ArrayList resultListTemp=新的ArrayList();
if(约束!=null)
{
//添加代码:停止键入延迟并修复错误:“适配器的内容已更改,但ListView未收到通知”
如果(conn!=null)
{
连接断开();
}
//更改代码:修复错误“适配器的内容已更改,但ListView未收到通知”:
resultListTemp.addAll(自动完成(constraint.toString());
filterResults.values=resultListTemp;
filterResults.count=resultListTemp.size();
}
返回过滤器结果;
}
@凌驾
受保护的void publishResults(CharSequence约束、FilterResults结果)
{
//添加代码:修复错误“适配器的内容已更改,但ListView未收到通知”:
resultList=(ArrayList)results.values;
if(results!=null&&results.count>0)
{
notifyDataSetChanged();
}
其他的
{
notifyDataSetionValidated();
}
}
专用ArrayList自动完成(字符串输入)
{
//更改代码:修复错误“适配器的内容已更改,但ListView未收到通知”:
ArrayList resultList=新的ArrayList();
.....
.....
}



其中“conn”是用于获取Google Places数据的HttpURLConnection。

如果它解决了您的问题。请就我的答案投票。这是一个鼓励所有人回答你的答案。谢谢你raguM.tech。我已经尝试过了:我将Google Places请求包装在一个AsyncTask中,并在afterTextChanged中调用它,这是可行的,但对于我键入的每个字符,下拉列表都会消失并再次出现(我如何避免这种情况,使下拉列表保持打开状态?),该AutoCompleteTextView已自动连接到TextWatcher,无需添加它,也无需使用过滤器。现在我有点不知道该用什么方法。有什么想法吗?那你得用EndlessAdapter。塔克斯!这加上在performFiltering中添加临时“resultListTemp”,还将处理错误消息:“适配器的内容已更改,但ListView未收到通知”。我认为Google Places Autocomplete培训应该用这些东西更新。您提到了适配器。NotifydataSetChange()。如果没有,请使用此函数在ListView中进行更改。那么只有listview没有更新。@raguM.tech:没错。notifyDataSetChanged()已包含在Googgle Places培训示例中。如果我使用的是volley而不是HttpURLConnection,该怎么办?