/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.support.v4.widget; import android.app.SearchManager; import android.content.ComponentName; import android.content.Context; import android.os.Build; import android.view.View; import android.widget.TextView; /** * Helper for accessing features in {@link android.widget.SearchView} * introduced after API level 4 in a backwards compatible fashion. */ public final class SearchViewCompat { interface SearchViewCompatImpl { View newSearchView(Context context); void setSearchableInfo(View searchView, ComponentName searchableComponent); void setImeOptions(View searchView, int imeOptions); void setInputType(View searchView, int inputType); Object newOnQueryTextListener(OnQueryTextListenerCompat listener); void setOnQueryTextListener(Object searchView, Object listener); Object newOnCloseListener(OnCloseListenerCompat listener); void setOnCloseListener(Object searchView, Object listener); CharSequence getQuery(View searchView); void setQuery(View searchView, CharSequence query, boolean submit); void setQueryHint(View searchView, CharSequence hint); void setIconified(View searchView, boolean iconify); boolean isIconified(View searchView); void setSubmitButtonEnabled(View searchView, boolean enabled); boolean isSubmitButtonEnabled(View searchView); void setQueryRefinementEnabled(View searchView, boolean enable); boolean isQueryRefinementEnabled(View searchView); void setMaxWidth(View searchView, int maxpixels); } static class SearchViewCompatStubImpl implements SearchViewCompatImpl { @Override public View newSearchView(Context context) { return null; } @Override public void setSearchableInfo(View searchView, ComponentName searchableComponent) { } @Override public void setImeOptions(View searchView, int imeOptions) { } @Override public void setInputType(View searchView, int inputType) { } @Override public Object newOnQueryTextListener(OnQueryTextListenerCompat listener) { return null; } @Override public void setOnQueryTextListener(Object searchView, Object listener) { } @Override public Object newOnCloseListener(OnCloseListenerCompat listener) { return null; } @Override public void setOnCloseListener(Object searchView, Object listener) { } @Override public CharSequence getQuery(View searchView) { return null; } @Override public void setQuery(View searchView, CharSequence query, boolean submit) { } @Override public void setQueryHint(View searchView, CharSequence hint) { } @Override public void setIconified(View searchView, boolean iconify) { } @Override public boolean isIconified(View searchView) { return true; } @Override public void setSubmitButtonEnabled(View searchView, boolean enabled) { } @Override public boolean isSubmitButtonEnabled(View searchView) { return false; } @Override public void setQueryRefinementEnabled(View searchView, boolean enable) { } @Override public boolean isQueryRefinementEnabled(View searchView) { return false; } @Override public void setMaxWidth(View searchView, int maxpixels) { } } static class SearchViewCompatHoneycombImpl extends SearchViewCompatStubImpl { @Override public View newSearchView(Context context) { return SearchViewCompatHoneycomb.newSearchView(context); } @Override public void setSearchableInfo(View searchView, ComponentName searchableComponent) { SearchViewCompatHoneycomb.setSearchableInfo(searchView, searchableComponent); } @Override public Object newOnQueryTextListener(final OnQueryTextListenerCompat listener) { return SearchViewCompatHoneycomb.newOnQueryTextListener( new SearchViewCompatHoneycomb.OnQueryTextListenerCompatBridge() { @Override public boolean onQueryTextSubmit(String query) { return listener.onQueryTextSubmit(query); } @Override public boolean onQueryTextChange(String newText) { return listener.onQueryTextChange(newText); } }); } @Override public void setOnQueryTextListener(Object searchView, Object listener) { SearchViewCompatHoneycomb.setOnQueryTextListener(searchView, listener); } @Override public Object newOnCloseListener(final OnCloseListenerCompat listener) { return SearchViewCompatHoneycomb.newOnCloseListener( new SearchViewCompatHoneycomb.OnCloseListenerCompatBridge() { @Override public boolean onClose() { return listener.onClose(); } }); } @Override public void setOnCloseListener(Object searchView, Object listener) { SearchViewCompatHoneycomb.setOnCloseListener(searchView, listener); } @Override public CharSequence getQuery(View searchView) { return SearchViewCompatHoneycomb.getQuery(searchView); } @Override public void setQuery(View searchView, CharSequence query, boolean submit) { SearchViewCompatHoneycomb.setQuery(searchView, query, submit); } @Override public void setQueryHint(View searchView, CharSequence hint) { SearchViewCompatHoneycomb.setQueryHint(searchView, hint); } @Override public void setIconified(View searchView, boolean iconify) { SearchViewCompatHoneycomb.setIconified(searchView, iconify); } @Override public boolean isIconified(View searchView) { return SearchViewCompatHoneycomb.isIconified(searchView); } @Override public void setSubmitButtonEnabled(View searchView, boolean enabled) { SearchViewCompatHoneycomb.setSubmitButtonEnabled(searchView, enabled); } @Override public boolean isSubmitButtonEnabled(View searchView) { return SearchViewCompatHoneycomb.isSubmitButtonEnabled(searchView); } @Override public void setQueryRefinementEnabled(View searchView, boolean enable) { SearchViewCompatHoneycomb.setQueryRefinementEnabled(searchView, enable); } @Override public boolean isQueryRefinementEnabled(View searchView) { return SearchViewCompatHoneycomb.isQueryRefinementEnabled(searchView); } @Override public void setMaxWidth(View searchView, int maxpixels) { SearchViewCompatHoneycomb.setMaxWidth(searchView, maxpixels); } } static class SearchViewCompatIcsImpl extends SearchViewCompatHoneycombImpl { @Override public View newSearchView(Context context) { return SearchViewCompatIcs.newSearchView(context); } @Override public void setImeOptions(View searchView, int imeOptions) { SearchViewCompatIcs.setImeOptions(searchView, imeOptions); } @Override public void setInputType(View searchView, int inputType) { SearchViewCompatIcs.setInputType(searchView, inputType); } } private static final SearchViewCompatImpl IMPL; static { if (Build.VERSION.SDK_INT >= 14) { // ICS IMPL = new SearchViewCompatIcsImpl(); } else if (Build.VERSION.SDK_INT >= 11) { // Honeycomb IMPL = new SearchViewCompatHoneycombImpl(); } else { IMPL = new SearchViewCompatStubImpl(); } } private SearchViewCompat(Context context) { /* Hide constructor */ } /** * Creates a new SearchView. * * @param context The Context the view is running in. * @return A SearchView instance if the class is present on the current * platform, null otherwise. */ public static View newSearchView(Context context) { return IMPL.newSearchView(context); } /** * Sets the SearchableInfo for this SearchView. Properties in the SearchableInfo are used * to display labels, hints, suggestions, create intents for launching search results screens * and controlling other affordances such as a voice button. * * @param searchView The SearchView to operate on. * @param searchableComponent The application component whose * {@link android.app.SearchableInfo} should be loaded and applied to * the SearchView. */ public static void setSearchableInfo(View searchView, ComponentName searchableComponent) { IMPL.setSearchableInfo(searchView, searchableComponent); } /** * Sets the IME options on the query text field. This is a no-op if * called on pre-{@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} * platforms. * * @see TextView#setImeOptions(int) * @param searchView The SearchView to operate on. * @param imeOptions the options to set on the query text field */ public static void setImeOptions(View searchView, int imeOptions) { IMPL.setImeOptions(searchView, imeOptions); } /** * Sets the input type on the query text field. This is a no-op if * called on pre-{@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} * platforms. * * @see TextView#setInputType(int) * @param searchView The SearchView to operate on. * @param inputType the input type to set on the query text field */ public static void setInputType(View searchView, int inputType) { IMPL.setInputType(searchView, inputType); } /** * Sets a listener for user actions within the SearchView. * * @param searchView The SearchView in which to register the listener. * @param listener the listener object that receives callbacks when the user performs * actions in the SearchView such as clicking on buttons or typing a query. */ public static void setOnQueryTextListener(View searchView, OnQueryTextListenerCompat listener) { IMPL.setOnQueryTextListener(searchView, listener.mListener); } /** * Callbacks for changes to the query text. */ public static abstract class OnQueryTextListenerCompat { final Object mListener; public OnQueryTextListenerCompat() { mListener = IMPL.newOnQueryTextListener(this); } /** * Called when the user submits the query. This could be due to a key press on the * keyboard or due to pressing a submit button. * The listener can override the standard behavior by returning true * to indicate that it has handled the submit request. Otherwise return false to * let the SearchView handle the submission by launching any associated intent. * * @param query the query text that is to be submitted * * @return true if the query has been handled by the listener, false to let the * SearchView perform the default action. */ public boolean onQueryTextSubmit(String query) { return false; } /** * Called when the query text is changed by the user. * * @param newText the new content of the query text field. * * @return false if the SearchView should perform the default action of showing any * suggestions if available, true if the action was handled by the listener. */ public boolean onQueryTextChange(String newText) { return false; } } /** * Sets a listener to inform when the user closes the SearchView. * * @param searchView The SearchView in which to register the listener. * @param listener the listener to call when the user closes the SearchView. */ public static void setOnCloseListener(View searchView, OnCloseListenerCompat listener) { IMPL.setOnCloseListener(searchView, listener.mListener); } /** * Callback for closing the query UI. */ public static abstract class OnCloseListenerCompat { final Object mListener; public OnCloseListenerCompat() { mListener = IMPL.newOnCloseListener(this); } /** * The user is attempting to close the SearchView. * * @return true if the listener wants to override the default behavior of clearing the * text field and dismissing it, false otherwise. */ public boolean onClose() { return false; } } /** * Returns the query string currently in the text field. * * @param searchView The SearchView to operate on. * * @return the query string */ public static CharSequence getQuery(View searchView) { return IMPL.getQuery(searchView); } /** * Sets a query string in the text field and optionally submits the query as well. * * @param searchView The SearchView to operate on. * @param query the query string. This replaces any query text already present in the * text field. * @param submit whether to submit the query right now or only update the contents of * text field. */ public static void setQuery(View searchView, CharSequence query, boolean submit) { IMPL.setQuery(searchView, query, submit); } /** * Sets the hint text to display in the query text field. This overrides any hint specified * in the SearchableInfo. * * @param searchView The SearchView to operate on. * @param hint the hint text to display */ public static void setQueryHint(View searchView, CharSequence hint) { IMPL.setQueryHint(searchView, hint); } /** * Iconifies or expands the SearchView. Any query text is cleared when iconified. This is * a temporary state and does not override the default iconified state set by * setIconifiedByDefault(boolean). If the default state is iconified, then * a false here will only be valid until the user closes the field. And if the default * state is expanded, then a true here will only clear the text field and not close it. * * @param searchView The SearchView to operate on. * @param iconify a true value will collapse the SearchView to an icon, while a false will * expand it. */ public static void setIconified(View searchView, boolean iconify) { IMPL.setIconified(searchView, iconify); } /** * Returns the current iconified state of the SearchView. * * @param searchView The SearchView to operate on. * @return true if the SearchView is currently iconified, false if the search field is * fully visible. */ public static boolean isIconified(View searchView) { return IMPL.isIconified(searchView); } /** * Enables showing a submit button when the query is non-empty. In cases where the SearchView * is being used to filter the contents of the current activity and doesn't launch a separate * results activity, then the submit button should be disabled. * * @param searchView The SearchView to operate on. * @param enabled true to show a submit button for submitting queries, false if a submit * button is not required. */ public static void setSubmitButtonEnabled(View searchView, boolean enabled) { IMPL.setSubmitButtonEnabled(searchView, enabled); } /** * Returns whether the submit button is enabled when necessary or never displayed. * * @param searchView The SearchView to operate on. * @return whether the submit button is enabled automatically when necessary */ public static boolean isSubmitButtonEnabled(View searchView) { return IMPL.isSubmitButtonEnabled(searchView); } /** * Specifies if a query refinement button should be displayed alongside each suggestion * or if it should depend on the flags set in the individual items retrieved from the * suggestions provider. Clicking on the query refinement button will replace the text * in the query text field with the text from the suggestion. This flag only takes effect * if a SearchableInfo has been specified with {@link #setSearchableInfo(View, ComponentName)} * and not when using a custom adapter. * * @param searchView The SearchView to operate on. * @param enable true if all items should have a query refinement button, false if only * those items that have a query refinement flag set should have the button. * * @see SearchManager#SUGGEST_COLUMN_FLAGS * @see SearchManager#FLAG_QUERY_REFINEMENT */ public static void setQueryRefinementEnabled(View searchView, boolean enable) { IMPL.setQueryRefinementEnabled(searchView, enable); } /** * Returns whether query refinement is enabled for all items or only specific ones. * @param searchView The SearchView to operate on. * @return true if enabled for all items, false otherwise. */ public static boolean isQueryRefinementEnabled(View searchView) { return IMPL.isQueryRefinementEnabled(searchView); } /** * Makes the view at most this many pixels wide * @param searchView The SearchView to operate on. */ public static void setMaxWidth(View searchView, int maxpixels) { IMPL.setMaxWidth(searchView, maxpixels); } }