如何在保留字符状态的情况下动态向 autocompletetextview 添加建议
Posted
技术标签:
【中文标题】如何在保留字符状态的情况下动态向 autocompletetextview 添加建议【英文标题】:How to dynamically add suggestions to autocompletetextview with preserving character status 【发布时间】:2013-11-20 10:48:27 【问题描述】:问题描述:
我在使用 AutoCompleteTextView 时遇到了一些问题,我必须在每次按键后显示建议。 问题是,建议列表是动态的,就像谷歌的建议功能一样。 这意味着应在用户不断输入时添加新建议,并应显示所有匹配的旧建议。
例如
我写“te”,然后它应该显示以前的建议,如“test1”和“test2”,以及我将从 Web API 获得的新建议。假设 web api 给了我“茶”和“紧张”这个词。
现在 AutoCompleteTextView 将有“te”作为字符串,下面显示所有四个建议。
这正是我想要的。
看起来很简单,但它表现出一种奇怪的行为。
我正在使用全局声明的默认 ArrayAdapter 类实例。
arrayAdapter=new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line,suggestions);
word.setAdapter(arrayAdapter);
建议是 ArrayList。
从 WebApi 获得新结果后,我只需调用
arrayAdapter.notifyDataSetChanged();
刷新数据观察者和附加的视图(在我们的例子中是 AutoCompleteListView)。
但它会关闭建议。
当我不使用 notifyDataSetChanged();
时,它会显示所有建议,无论我输入了什么字符。
我尝试了许多建议的自定义过滤器,但没有一个有用,因为我无法使用 notifyDataSetChanged()。
我张贴图片以避免混淆。
我很困惑为什么notifyDataSetChanged();
不起作用。我没有使用具有相同 arrayAdapter 实例的任何其他列表引用。我真的怀疑这是否是一个参考问题。
【问题讨论】:
何时以及如何将网络结果添加到适配器? @pskink:我将它添加到 ArrayList 的建议中。然后我调用 notifyDataSetChanged()。我在从 WebApi 获取结果的 Asynctask 的 postExecute() 中执行此操作。 您应该在适配器过滤器的 performFilteting/publishResults 方法中执行此操作 我没试过。让我检查一下。 或者您可以使用现有的过滤器,如 CursorFilter 及其与 CursorAdapter 的集成,请参阅下面的答案 【参考方案1】:最简单的方法之一(将代码放在 onCreate 中):
编辑:添加***免费开放搜索(如果 https://en.wikipedia.org 不起作用,请尝试 http://en.wikipedia.org)
AutoCompleteTextView actv = new AutoCompleteTextView(this);
actv.setThreshold(1);
String[] from = "name", "description" ;
int[] to = android.R.id.text1, android.R.id.text2 ;
SimpleCursorAdapter a = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, null, from, to, 0);
a.setStringConversionColumn(1);
FilterQueryProvider provider = new FilterQueryProvider()
@Override
public Cursor runQuery(CharSequence constraint)
// run in the background thread
Log.d(TAG, "runQuery constraint: " + constraint);
if (constraint == null)
return null;
String[] columnNames = BaseColumns._ID, "name", "description" ;
MatrixCursor c = new MatrixCursor(columnNames);
try
String urlString = "https://en.wikipedia.org/w/api.php?" +
"action=opensearch&search=" + constraint +
"&limit=8&namespace=0&format=json";
URL url = new URL(urlString);
InputStream stream = url.openStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String jsonStr = reader.readLine();
// output ["query", ["n0", "n1", ..], ["d0", "d1", ..]]
JSONArray json = new JSONArray(jsonStr);
JSONArray names = json.getJSONArray(1);
JSONArray descriptions = json.getJSONArray(2);
for (int i = 0; i < names.length(); i++)
c.newRow().add(i).add(names.getString(i)).add(descriptions.getString(i));
catch (Exception e)
e.printStackTrace();
return c;
;
a.setFilterQueryProvider(provider);
actv.setAdapter(a);
setContentView(actv, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
【讨论】:
嘿,我得到了解决方案,您的评论是对的。它帮助我部分解决了问题。虽然我也有其他一些我目前正在处理的问题。我没有检查这种方式来获得答案,因为我不想将数据库用于这个单一目的。我感谢您的全力支持,并为此给予您更多的支持。感谢您的所有帮助。 我不使用任何数据库,数据是从 json web 服务读取的 到目前为止,我尝试了很多不同的东西:TextWatcher、AsyncTask 等。这正是我一直在寻找的!我能找到的最好的代码。完美运行! @OlivierP。简单而有效,不是吗?不幸的是,即使他们看到了这个如此简单的解决方案,这里 90% 的人仍然想与那些观察者、自定义 ArrayAdapters、AsyncTasks 等进行斗争,我不知道为什么...... @pskink 我是其中之一 ^^ 我不知道这可以通过这种方式完成。我很高兴找到你的代码。此外,当您通过 Internet、*** 等进行搜索时,您的答案肯定不是突出显示的答案!【参考方案2】:您已经在 ArrayAdapter 的子类中实现了自定义过滤器,在执行过滤器方法中您必须进行网络调用并从服务器获取数据。您可以在主数组列表中设置此数据。
【讨论】:
以上是关于如何在保留字符状态的情况下动态向 autocompletetextview 添加建议的主要内容,如果未能解决你的问题,请参考以下文章
在 Kotlin Native 中,如何在不使用 C 指针的情况下将对象保留在单独的线程中,并从任何其他线程中改变其状态?
如何在没有百分比编码的情况下在 Swift URL 中包含重音字符?
如何在不删除 Ionic 3 的情况下使 iOS 上的状态栏透明?