How to dynamically add suggestions to autocomplete

2018-12-31 01:03发布

Problem Description:

I am facing some problem with AutoCompleteTextView where I have to show suggestions after each keypress. Thing is that, list of suggestion is dynamic like google's suggestion feature. It means the new suggestions should be added as user keeps typing in plus all matching old suggestions should be displayed.

For example

I write "te" and then it should display previous suggestions like "test1" & "test2" and the new suggestions that I will get from Web API. Suppose web api gives me word "tea"& "tension ".

Now the AutoCompleteTextView will have "te" as string with all four suggestions showing below it.

This is exactly what I am looking for.

looks simple but it is showing a strange behaviour.

I am using default ArrayAdapter class instance of which I am declaring globally.

arrayAdapter=new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line,suggestions);
word.setAdapter(arrayAdapter);

suggestions is ArrayList.

Upon getting new result from WebApi I simply call

arrayAdapter.notifyDataSetChanged();

to refresh the data observer and views attached with this (in our case AutoCompleteListView).

But it closes suggestions.

When I don't use notifyDataSetChanged(); it is showing all suggestions regardless of characters I have typed.

I tried it with custom filter as many suggested but none of them is helpful as I couldn't use notifyDataSetChanged().

I am posting an image to avoid confusions.enter image description here

I have a confusion that why notifyDataSetChanged(); its not working. I haven't use any other reference of list with same arrayAdapter instance. I really doubt if it's a reference problem.

2条回答
与君花间醉酒
2楼-- · 2018-12-31 01:20

one of the easiest way of doing that (put the code in onCreate):

EDIT: addied wikipedia free opensearch (if https://en.wikipedia.org doesn't work try 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));
查看更多
人气声优
3楼-- · 2018-12-31 01:37

You have impletent the custome filter in the child class of ArrayAdapter, there in perform filter method you have to do network call and get data from server. You can set this data in your main arraylist.

查看更多
登录 后发表回答