问题描述:
我在使用AutoCompleteTextView时遇到一些问题,我必须在每次按键后显示建议。 事情是,建议列表是动态像谷歌的建议功能。 这意味着应该在用户输入时添加新建议,并且应显示所有匹配的旧建议。
例如
我写“te”然后它应该显示之前的建议,如“test1”& “test2”以及我将从Web API获得的新建议。假设web api给了我“茶”字样的信息。 “紧张”。
现在,AutoCompleteTextView将“te”作为字符串,并在其下方显示所有四个建议。
这正是我要找的。 p>
看起来很简单,但却显示出一种奇怪的行为。
我正在使用我在全球范围内声明的默认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实例的任何其他列表引用。我真的怀疑这是否是一个参考问题。
答案 0 :(得分:17)
最简单的方法之一(将代码放在onCreate中):
编辑:addied wikipedia免费opensearch(如果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));
答案 1 :(得分:0)
您已在ArrayAdapter的子类中实现了custome过滤器,在执行过滤方法时您必须进行网络调用并从服务器获取数据。您可以在主要的arraylist中设置此数据。