动态更新AutoCompleteTextView适配器

jay*_*bee 37 android autocomplete autocompletetextview

我想通过从RESTful Web服务获取列表来定期更改AutoCompleteTextview给出的建议,但无法使其顺利运行.我建立了一个硬编码的建议列表,以确保它的工作:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, new String[] {"Hi", "Ho"});
speciesName.setAdapter(adapter);//my autocomplete tv
Run Code Online (Sandbox Code Playgroud)

我在textview上有一个TextWatcher,当文本发生变化时,会启动一个非阻塞调用来获取新的建议列表 - 这个获得新列表的部分工作正常.然后我想重置适配器,如下所示:

public void setOptionsAndUpdate(String[] options) {
    Log.d(TAG, "setting options");
    //speciesName.setAdapter((ArrayAdapter<String>)null);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, options);
    speciesName.setAdapter(adapter);
}
Run Code Online (Sandbox Code Playgroud)

此方法被调用,但不起作用 - 建议列表消失或显示的建议保持不变,尽管调用setAdapter.

这甚至是正确的方法吗?我看了看SimpleCursorAdapter但无法看到如何将我的网络服务注册为内容提供商.(它的格式为http://www.blah.com/query?term=XX,其中XX是我的应用程序的输入,响应是JSON数组字符串.)

GLe*_*Lee 45

在动态添加和更改适配器中的数据时,我没有运气使用adapter.notifyDataSetChanged().在我的情况下,我异步地击中外部api并定期获取完成数据列表.

此代码清除适配器,并按预期添加新数据.但是,我必须调用getFilter().Filter方法来强制显示数据.另外,我必须根据AutocompleteTextView中的当前文本显式过滤,因为我的api调用是异步的.

adapter.clear();
for (Map<String, String> map : completions) {
     adapter.add(map.get("name"));
}

//Force the adapter to filter itself, necessary to show new data.
//Filter based on the current text because api call is asynchronous. 
adapter.getFilter().filter(autocompleteTextView.getText(), null);
Run Code Online (Sandbox Code Playgroud)

  • 而不是传入`null`,你可以传入`autocompleteTextView` 使其行为与`AutoCompleteTextView.performFiltering()` 相同 - 这是通常在文本更改后调用的方法 (2认同)

小智 23

有在使用谷歌地图API的远程数据来填充AutoCompleteTextView这个话题相当不错教程这里.

如果您需要缓存版本,我会从此处检索它.原始教程已被删除,但基本上您需要使用自定义过滤器编写ArrayAdapter,其方式与下面所示类似,并将其分配给AutoCompleteTextView.

注意:您需要实现一个方法autocomplete(),它执行同步获取和返回自动完成项所需的任何操作.由于在后台线程中调用过滤器,因此不会阻止主UI线程.

private class PlacesAutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {
private ArrayList<String> resultList;

public PlacesAutoCompleteAdapter(Context context, int textViewResourceId) {
    super(context, textViewResourceId);
}

@Override
public int getCount() {
    return resultList.size();
}

@Override
public String getItem(int index) {
    return resultList.get(index);
}

@Override
public Filter getFilter() {
    Filter filter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();
            if (constraint != null) {
                // Retrieve the autocomplete results.
                resultList = autocomplete(constraint.toString());

                // Assign the data to the FilterResults
                filterResults.values = resultList;
                filterResults.count = resultList.size();
            }
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results != null && results.count > 0) {
                notifyDataSetChanged();
            }
            else {
                notifyDataSetInvalidated();
            }
        }};
    return filter;
}
}
Run Code Online (Sandbox Code Playgroud)


ser*_*zel 19

这是我更新我的AutoCompleteTextView的方式:

String[] data = terms.toArray(new String[terms.size()]);  // terms is a List<String>
ArrayAdapter<?> adapter = new ArrayAdapter<Object>(activity, android.R.layout.simple_dropdown_item_1line, data);
keywordField.setAdapter(adapter);  // keywordField is a AutoCompleteTextView
if(terms.size() < 40) keywordField.setThreshold(1); 
else keywordField.setThreshold(2);
Run Code Online (Sandbox Code Playgroud)

当然,这是静态的,并不处理无线建议,但是,我还建议您在将更改分配给AutoCompleteTextView后通知适配器:

adapter.notifyDataSetChanged();   
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

-serkan