12

问题描述:

我在使用 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 实例的任何其他列表引用。我真的怀疑这是否是一个参考问题。

4

2 回答 2

19

最简单的方法之一(将代码放在 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));
于 2013-11-08T13:49:15.360 回答
0

您已经在 ArrayAdapter 的子类中实现了自定义过滤器,在执行过滤器方法中您必须进行网络调用并从服务器获取数据。您可以在主数组列表中设置此数据。

于 2017-08-19T05:23:28.720 回答