Turn AutoCompleteTextView into a SearchView in ActionBar instead

AutoCompleteTextView with google search Api

enter image description here

your xml

  <AutoCompleteTextView
    android:id="@+id/main_omnibox_input"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:background="@null" 
    android:hint="Search"  
    android:focusable="true"
    android:focusableInTouchMode="true"                                  
    android:selectAllOnFocus="true"
    android:singleLine="true" 
    android:textSize="@dimen/_14sdp" />

your java code

  this.inputBox = (AutoCompleteTextView) findViewById(R.id.main_omnibox_input);
  inputBox.setAdapter(new SearchAutocompleteAdapter(SearchActivity.this, new SearchAutocompleteAdapter.OnSearchCommitListener() {
        @Override
        public void onSearchCommit(String text) {
            inputBox.setText(text);
            inputBox.setSelection(text.length());
        }
    }));


    this.inputBox.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long j) {
            String charSequence = ((TextView) view.findViewById(android.R.id.text1)).getText().toString();
            inputBox.setText(Html.fromHtml(BrowserUnit.urlWrapper(charSequence)), BufferType.SPANNABLE);
            inputBox.setSelection(charSequence.length());
           // your code
           // updateAlbum(charSequence);
           // hideSoftInput(SearchActivity.this.inputBox);
        }
    });

SearchAutocompleteAdapter

public class SearchAutocompleteAdapter extends BaseAdapter implements Filterable {

interface OnSearchCommitListener {
    void onSearchCommit(String text);
}

private final Context mContext;
private final OnSearchCommitListener commitListener;
private List<String> completions = new ArrayList<>();
static final String searchCompleteUrl = "https://www.google.com/complete/search?client=firefox&q=%s";

SearchAutocompleteAdapter(Context context, OnSearchCommitListener commitListener) {
    mContext = context;
    this.commitListener = commitListener;
}

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

@Override
public Object getItem(int position) {
    return completions.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@SuppressLint("ClickableViewAccessibility")
@Override
@SuppressWarnings("ConstantConditions")
public View getView(final int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false);
    }
    TextView textview = convertView.findViewById(android.R.id.text1);
    textview.setText(completions.get(position));
    Drawable d = ContextCompat.getDrawable(mContext, R.drawable.icon_goarrowsmall);
    final int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32, mContext.getResources().getDisplayMetrics());
    d.setBounds(0, 0, size, size);
    textview.setCompoundDrawables(null, null, d, null);

    textview.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            if (event.getAction() != MotionEvent.ACTION_DOWN) {
                return false;
            }
            TextView t = (TextView) view;
            if (event.getX() > t.getWidth() - t.getCompoundPaddingRight()) {
                commitListener.onSearchCommit(getItem(position).toString());
                return true;
            }
            return false;
        }
    });
    parent.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            if (event.getX() > view.getWidth() - size * 2) {
                return true;
            }
            return false;
        }
    });
    return convertView;
}

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            // Invoked on a worker thread
            FilterResults filterResults = new FilterResults();
            if (constraint != null) {
                List<String> results = getCompletions(constraint.toString());
                filterResults.values = results;
                filterResults.count = results.size();
            }
            return filterResults;
        }

        @Override
        @SuppressWarnings("unchecked")
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results != null && results.count > 0) {
                completions = (List<String>) results.values;
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    };
}

private List<String> getCompletions(String text) {
    int total = 0;
    byte[] data = new byte[16384];
    try {
        URL url = new URL(URLUtil.composeSearchUrl(text, searchCompleteUrl, "%s"));
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        try {
            InputStream in = new BufferedInputStream(urlConnection.getInputStream());
            while (total <= data.length) {
                int count = in.read(data, total, data.length - total);
                if (count == -1) {
                    break;
                }
                total += count;
            }
            if (total == data.length) {
                // overflow
                return new ArrayList<>();
            }
        } finally {
            urlConnection.disconnect();
        }
    } catch (IOException e) {
        return new ArrayList<>();
    }

    JSONArray jsonArray;
    try {
        jsonArray = new JSONArray(new String(data, StandardCharsets.UTF_8));
    } catch (JSONException e) {
        return new ArrayList<>();
    }
    jsonArray = jsonArray.optJSONArray(1);
    if (jsonArray == null) {
        return new ArrayList<>();
    }
    final int MAX_RESULTS = 10;
    List<String> result = new ArrayList<>(Math.min(jsonArray.length(), MAX_RESULTS));
    for (int i = 0; i < jsonArray.length() && result.size() < MAX_RESULTS; i++) {
        String s = jsonArray.optString(i);
        if (s != null && !s.isEmpty()) {
            result.add(s);
        }
    }
    return result;
}

}


To get Places Autocomplete API results in a SearchView, you'll first need a ContentProvider for the API.

import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.util.Log;

public class PlacesSuggestionProvider extends ContentProvider {
    private static final String LOG_TAG = "ExampleApp";

    public static final String AUTHORITY = "com.example.google.places.search_suggestion_provider";
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/search");

    // UriMatcher constant for search suggestions
    private static final int SEARCH_SUGGEST = 1;

    private static final UriMatcher uriMatcher;

    private static final String[] SEARCH_SUGGEST_COLUMNS = {
            BaseColumns._ID,
            SearchManager.SUGGEST_COLUMN_TEXT_1,
            SearchManager.SUGGEST_COLUMN_TEXT_2,
            SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID
    };

    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);
        uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST);
    }

    @Override
    public int delete(Uri uri, String arg1, String[] arg2) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case SEARCH_SUGGEST:
                return SearchManager.SUGGEST_MIME_TYPE;
            default:
                throw new IllegalArgumentException("Unknown URL " + uri);
        }
    }

    @Override
    public Uri insert(Uri uri, ContentValues arg1) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean onCreate() {
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        Log.d(LOG_TAG, "query = " + uri);

        // Use the UriMatcher to see what kind of query we have
        switch (uriMatcher.match(uri)) {
            case SEARCH_SUGGEST:
                Log.d(LOG_TAG, "Search suggestions requested.");
                MatrixCursor cursor = new MatrixCursor(SEARCH_SUGGEST_COLUMNS, 1);
                cursor.addRow(new String[] {
                        "1", "Search Result", "Search Result Description", "content_id"
                });
                return cursor;
            default:
                throw new IllegalArgumentException("Unknown Uri: " + uri);
        }
    }

    @Override
    public int update(Uri uri, ContentValues arg1, String arg2, String[] arg3) {
        throw new UnsupportedOperationException();
    }
}

Then add your Places Autocomplete API client code into the query method on the content provider. You extract the user input as follows:

String query = uri.getLastPathSegment().toLowerCase();

Add the PlacesSuggestionProvider to your AndroidManifest, and make sure your activity has a searchable configuration.

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >

        <activity android:name=".PlacesSearchViewActivity" >
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>

        <provider
            android:name="com.example.google.places.PlacesSuggestionProvider"
            android:authorities="com.example.google.places.search_suggestion_provider"
            android:syncable="false" />
    </application>

</manifest>

And make sure your searchable configuration (res/xml/searchable.xml) has a search suggest authority.

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_name"
    android:hint="@string/search_hint"
    android:searchSuggestAuthority="com.example.google.places.search_suggestion_provider">
</searchable>

The authority should be the same in AndroidManifest.xml, searchable.xml, and your content provider.

Create a options menu for your ActionBar that includes a SearchView (/res/menu/options_menu.xml).

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_search"
          android:title="@string/menu_search"
          android:icon="@drawable/ic_menu_search"
          android:showAsAction="collapseActionView|ifRoom"
          android:actionViewClass="android.widget.SearchView" />
</menu>

Configure your Activity with a SearchView that's associated with your searchable configuration/

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the options menu from XML
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
    // Tells your app's SearchView to use this activity's searchable configuration
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default

    return true;
}

A few key docs are:

Adding Custom Suggestions: http://developer.android.com/guide/topics/search/adding-custom-suggestions.html

Creating a Content Provider: http://developer.android.com/guide/topics/providers/content-provider-creating.html

Using a Search Widget: http://developer.android.com/guide/topics/search/search-dialog.html#UsingSearchWidget