Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement search view autocomplete in actionbar using http request?

I've added search view widget to my action bar and would like to handle autocomplete feature. After writing more then 3 letters it should fulfill http request to my web API which will return json result and should show search widget suggestions. But in documentation is observed the case with content providers. How can I organize autocomplete feature?

Added search view in menu xml file:

    <item android:id="@+id/search"
    android:icon="@drawable/ic_search_white_24dp"
    android:title="Search"
    [namespace]:showAsAction="always"
    [namespace]:actionViewClass="android.widget.SearchView" />

Associates searchable configuration with the SearchView:

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.navigation, menu);

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

    return super.onCreateOptionsMenu(menu);
}

Added searchable configuration:

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_name"
    android:hint="@string/search_hint"
    android:searchSuggestAuthority="com.my.domain.searchable_activity" />

And ultimately added empty responsible activity.

like image 502
Tigran Vardanyan Avatar asked Jun 06 '16 12:06

Tigran Vardanyan


1 Answers

You can't do this with setSearchableInfo() and a search configuration.

The problem is that SearchView needs a CursorAdapter and you are retrieving data from the server, not the database.

However, I have done something like this before with these steps:

  • Set up your SearchView to use a CursorAdapter;

        searchView.setSuggestionsAdapter(new SimpleCursorAdapter(
                context, android.R.layout.simple_list_item_1, null, 
                new String[] { SearchManager.SUGGEST_COLUMN_TEXT_1 }, 
                new int[] { android.R.id.text1 }));
    
  • Create an AsyncTask to read the JSON data from your server and create a MatrixCursor from the data:

    public class FetchSearchTermSuggestionsTask extends AsyncTask<String, Void, Cursor> {
    
        private static final String[] sAutocompleteColNames = new String[] { 
                BaseColumns._ID,                         // necessary for adapter
                SearchManager.SUGGEST_COLUMN_TEXT_1      // the full search term
        };
    
        @Override
        protected Cursor doInBackground(String... params) {
    
            MatrixCursor cursor = new MatrixCursor(sAutocompleteColNames);
    
            // get your search terms from the server here, ex:
            JSONArray terms = remoteService.getTerms(params[0]);
    
            // parse your search terms into the MatrixCursor
            for (int index = 0; index < terms.length(); index++) {
                String term = terms.getString(index);
    
                Object[] row = new Object[] { index, term };
                cursor.addRow(row);
            }
    
            return cursor;
        }
    
        @Override
        protected void onPostExecute(Cursor result) {
            searchView.getSuggestionsAdapter().changeCursor(result);
        }
    
    }
    
  • Set an OnQueryTextListener to kick off your remote server task or start your search activity:

        searchView.setOnQueryTextListener(new OnQueryTextListener() {
    
            @Override
            public boolean onQueryTextChange(String query) {
    
                if (query.length() >= SEARCH_QUERY_THRESHOLD) {
                    new FetchSearchTermSuggestionsTask().execute(query);
                } else {
                    searchView.getSuggestionsAdapter().changeCursor(null);
                }
    
                return true;
            }
    
            @Override
            public boolean onQueryTextSubmit(String query) {
    
                // if user presses enter, do default search, ex:
                if (query.length() >= SEARCH_QUERY_THRESHOLD) {
    
                    Intent intent = new Intent(MainActivity.this, SearchableActivity.class);
                    intent.setAction(Intent.ACTION_SEARCH);
                    intent.putExtra(SearchManager.QUERY, query);
                    startActivity(intent);
    
                    searchView.getSuggestionsAdapter().changeCursor(null);
                    return true;
                }
            }
        });
    
  • Set an OnSuggestionListener on the SearchView to execute your search:

        searchView.setOnSuggestionListener(new OnSuggestionListener() {
    
            @Override
            public boolean onSuggestionSelect(int position) {
    
                Cursor cursor = (Cursor) searchView.getSuggestionsAdapter().getItem(position);
                String term = cursor.getString(cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1));
                cursor.close();
    
                Intent intent = new Intent(MainActivity.this, SearchableActivity.class);
                intent.setAction(Intent.ACTION_SEARCH);
                intent.putExtra(SearchManager.QUERY, term);
                startActivity(intent);
    
                return true;
            }
    
            @Override
            public boolean onSuggestionClick(int position) {
    
                return onSuggestionSelect(position);
            }
        });
    
like image 82
kris larson Avatar answered Sep 28 '22 04:09

kris larson