FileDocCategorySizeDatePackage
SearchFragment.javaAPI DocAndroid 5.1 API26298Thu Mar 12 22:22:56 GMT 2015android.support.v17.leanback.app

SearchFragment

public class SearchFragment extends android.app.Fragment
A fragment to handle searches. An application will supply an implementation of the {@link SearchResultProvider} interface to handle the search and return an {@link ObjectAdapter} containing the results. The results are rendered into a {@link RowsFragment}, in the same way that they are in a {@link BrowseFragment}.

If you do not supply a callback via {@link #setSpeechRecognitionCallback(SpeechRecognitionCallback)}, an internal speech recognizer will be used for which your application will need to request android.permission.RECORD_AUDIO.

Speech recognition is automatically started when fragment is created, but not when fragment is restored from an instance state. Activity may manually call {@link #startRecognition()}, typically in onNewIntent().

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private static final String
EXTRA_LEANBACK_BADGE_PRESENT
private static final String
ARG_PREFIX
private static final String
ARG_QUERY
private static final String
ARG_TITLE
private static final long
SPEECH_RECOGNITION_DELAY_MS
private static final int
RESULTS_CHANGED
private static final int
QUERY_COMPLETE
private final android.support.v17.leanback.widget.ObjectAdapter.DataObserver
mAdapterObserver
private final android.os.Handler
mHandler
private final Runnable
mResultsChangedCallback
private final Runnable
mSetSearchResultProvider
Runs when a new provider is set AND when the fragment view is created.
private final Runnable
mStartRecognitionRunnable
private RowsFragment
mRowsFragment
private android.support.v17.leanback.widget.SearchBar
mSearchBar
private SearchResultProvider
mProvider
private String
mPendingQuery
private android.support.v17.leanback.widget.OnItemSelectedListener
mOnItemSelectedListener
private android.support.v17.leanback.widget.OnItemClickedListener
mOnItemClickedListener
private android.support.v17.leanback.widget.OnItemViewSelectedListener
mOnItemViewSelectedListener
private android.support.v17.leanback.widget.OnItemViewClickedListener
mOnItemViewClickedListener
private android.support.v17.leanback.widget.ObjectAdapter
mResultAdapter
private android.support.v17.leanback.widget.SpeechRecognitionCallback
mSpeechRecognitionCallback
private String
mTitle
private android.graphics.drawable.Drawable
mBadgeDrawable
private ExternalQuery
mExternalQuery
private android.speech.SpeechRecognizer
mSpeechRecognizer
private int
mStatus
private boolean
mAutoStartRecognition
Constructors Summary
Methods Summary
private voidapplyExternalQuery()

        if (mExternalQuery == null || mSearchBar == null) {
            return;
        }
        mSearchBar.setSearchQuery(mExternalQuery.mQuery);
        if (mExternalQuery.mSubmit) {
            submitQuery(mExternalQuery.mQuery);
        }
        mExternalQuery = null;
    
public static android.os.BundlecreateArgs(android.os.Bundle args, java.lang.String query)

param
args Bundle to use for the arguments, if null a new Bundle will be created.


                         
           
        return createArgs(args, query, null);
    
public static android.os.BundlecreateArgs(android.os.Bundle args, java.lang.String query, java.lang.String title)

        if (args == null) {
            args = new Bundle();
        }
        args.putString(ARG_QUERY, query);
        args.putString(ARG_TITLE, title);
        return args;
    
public voiddisplayCompletions(java.util.List completions)
Display the completions shown by the IME. An application may provide a list of query completions that the system will show in the IME.

param
completions A list of completions to show in the IME. Setting to null or empty will clear the list.

        mSearchBar.displayCompletions(completions);
    
private voidexecutePendingQuery()

        if (null != mPendingQuery && null != mResultAdapter) {
            String query = mPendingQuery;
            mPendingQuery = null;
            retrieveResults(query);
        }
    
private voidfocusOnResults()

        if (mRowsFragment == null ||
                mRowsFragment.getVerticalGridView() == null ||
                mResultAdapter.size() == 0) {
            return;
        }
        if (mRowsFragment.getVerticalGridView().requestFocus()) {
            mStatus &= ~RESULTS_CHANGED;
        }
    
public android.graphics.drawable.DrawablegetBadgeDrawable()
Returns the badge drawable in the search bar.

        if (null != mSearchBar) {
            return mSearchBar.getBadgeDrawable();
        }
        return null;
    
public android.content.IntentgetRecognizerIntent()
Returns an intent that can be used to request speech recognition. Built from the base {@link RecognizerIntent#ACTION_RECOGNIZE_SPEECH} plus extras:
  • {@link RecognizerIntent#EXTRA_LANGUAGE_MODEL} set to {@link RecognizerIntent#LANGUAGE_MODEL_FREE_FORM}
  • {@link RecognizerIntent#EXTRA_PARTIAL_RESULTS} set to true
  • {@link RecognizerIntent#EXTRA_PROMPT} set to the search bar hint text
For handling the intent returned from the service, see {@link #setSearchQuery(Intent, boolean)}.

        Intent recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        recognizerIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
        if (mSearchBar != null && mSearchBar.getHint() != null) {
            recognizerIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, mSearchBar.getHint());
        }
        recognizerIntent.putExtra(EXTRA_LEANBACK_BADGE_PRESENT, mBadgeDrawable != null);
        return recognizerIntent;
    
public java.lang.StringgetTitle()
Returns the title set in the search bar.

        if (null != mSearchBar) {
            return mSearchBar.getTitle();
        }
        return null;
    
public static android.support.v17.leanback.app.SearchFragmentnewInstance(java.lang.String query)
Create a search fragment with a given search query.

You should only use this if you need to start the search fragment with a pre-filled query.

param
query The search query to begin with.
return
A new SearchFragment.

        SearchFragment fragment = new SearchFragment();
        Bundle args = createArgs(null, query);
        fragment.setArguments(args);
        return fragment;
    
public voidonCreate(android.os.Bundle savedInstanceState)

        if (mAutoStartRecognition) {
            mAutoStartRecognition = savedInstanceState == null;
        }
        super.onCreate(savedInstanceState);
    
public android.view.ViewonCreateView(android.view.LayoutInflater inflater, android.view.ViewGroup container, android.os.Bundle savedInstanceState)

        View root = inflater.inflate(R.layout.lb_search_fragment, container, false);

        FrameLayout searchFrame = (FrameLayout) root.findViewById(R.id.lb_search_frame);
        mSearchBar = (SearchBar) searchFrame.findViewById(R.id.lb_search_bar);
        mSearchBar.setSearchBarListener(new SearchBar.SearchBarListener() {
            @Override
            public void onSearchQueryChange(String query) {
                if (DEBUG) Log.v(TAG, String.format("onSearchQueryChange %s %s", query,
                        null == mProvider ? "(null)" : mProvider));
                if (null != mProvider) {
                    retrieveResults(query);
                } else {
                    mPendingQuery = query;
                }
            }

            @Override
            public void onSearchQuerySubmit(String query) {
                if (DEBUG) Log.v(TAG, String.format("onSearchQuerySubmit %s", query));
                submitQuery(query);
            }

            @Override
            public void onKeyboardDismiss(String query) {
                if (DEBUG) Log.v(TAG, String.format("onKeyboardDismiss %s", query));
                queryComplete();
            }
        });
        mSearchBar.setSpeechRecognitionCallback(mSpeechRecognitionCallback);
        applyExternalQuery();

        readArguments(getArguments());
        if (null != mBadgeDrawable) {
            setBadgeDrawable(mBadgeDrawable);
        }
        if (null != mTitle) {
            setTitle(mTitle);
        }

        // Inject the RowsFragment in the results container
        if (getChildFragmentManager().findFragmentById(R.id.lb_results_frame) == null) {
            mRowsFragment = new RowsFragment();
            getChildFragmentManager().beginTransaction()
                    .replace(R.id.lb_results_frame, mRowsFragment).commit();
        } else {
            mRowsFragment = (RowsFragment) getChildFragmentManager()
                    .findFragmentById(R.id.lb_results_frame);
        }
        mRowsFragment.setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
            @Override
            public void onItemSelected(ViewHolder itemViewHolder, Object item,
                    RowPresenter.ViewHolder rowViewHolder, Row row) {
                int position = mRowsFragment.getVerticalGridView().getSelectedPosition();
                if (DEBUG) Log.v(TAG, String.format("onItemSelected %d", position));
                mSearchBar.setVisibility(0 >= position ? View.VISIBLE : View.GONE);
                if (null != mOnItemSelectedListener) {
                    mOnItemSelectedListener.onItemSelected(item, row);
                }
                if (null != mOnItemViewSelectedListener) {
                    mOnItemViewSelectedListener.onItemSelected(itemViewHolder, item,
                            rowViewHolder, row);
                }
            }
        });
        mRowsFragment.setOnItemViewClickedListener(new OnItemViewClickedListener() {
            @Override
            public void onItemClicked(ViewHolder itemViewHolder, Object item,
                    RowPresenter.ViewHolder rowViewHolder, Row row) {
                int position = mRowsFragment.getVerticalGridView().getSelectedPosition();
                if (DEBUG) Log.v(TAG, String.format("onItemClicked %d", position));
                if (null != mOnItemClickedListener) {
                    mOnItemClickedListener.onItemClicked(item, row);
                }
                if (null != mOnItemViewClickedListener) {
                    mOnItemViewClickedListener.onItemClicked(itemViewHolder, item,
                            rowViewHolder, row);
                }
            }
        });
        mRowsFragment.setExpand(true);
        if (null != mProvider) {
            onSetSearchResultProvider();
        }
        return root;
    
public voidonDestroy()

        releaseAdapter();
        super.onDestroy();
    
public voidonPause()

        releaseRecognizer();
        super.onPause();
    
public voidonResume()

        super.onResume();
        if (mSpeechRecognitionCallback == null && null == mSpeechRecognizer) {
            mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(getActivity());
            mSearchBar.setSpeechRecognizer(mSpeechRecognizer);
        }
        // Ensure search bar state consistency when using external recognizer
        mSearchBar.stopRecognition();
    
private voidonSetSearchResultProvider()

        mHandler.removeCallbacks(mSetSearchResultProvider);
        mHandler.post(mSetSearchResultProvider);
    
public voidonStart()

        super.onStart();

        VerticalGridView list = mRowsFragment.getVerticalGridView();
        int mContainerListAlignTop =
                getResources().getDimensionPixelSize(R.dimen.lb_search_browse_rows_align_top);
        list.setItemAlignmentOffset(0);
        list.setItemAlignmentOffsetPercent(VerticalGridView.ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
        list.setWindowAlignmentOffset(mContainerListAlignTop);
        list.setWindowAlignmentOffsetPercent(VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
        list.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_NO_EDGE);
    
private voidqueryComplete()

        if (DEBUG) Log.v(TAG, "queryComplete");
        mStatus |= QUERY_COMPLETE;
        focusOnResults();
    
private voidreadArguments(android.os.Bundle args)

        if (null == args) {
            return;
        }
        if (args.containsKey(ARG_QUERY)) {
            setSearchQuery(args.getString(ARG_QUERY));
        }

        if (args.containsKey(ARG_TITLE)) {
            setTitle(args.getString(ARG_TITLE));
        }
    
private voidreleaseAdapter()

        if (mResultAdapter != null) {
            mResultAdapter.unregisterObserver(mAdapterObserver);
            mResultAdapter = null;
        }
    
private voidreleaseRecognizer()

        if (null != mSpeechRecognizer) {
            mSearchBar.setSpeechRecognizer(null);
            mSpeechRecognizer.destroy();
            mSpeechRecognizer = null;
        }
    
private voidresultsAvailable()

        if ((mStatus & QUERY_COMPLETE) != 0) {
            focusOnResults();
        }
        updateSearchBarNextFocusId();
    
private voidretrieveResults(java.lang.String searchQuery)

        if (DEBUG) Log.v(TAG, "retrieveResults " + searchQuery);
        if (mProvider.onQueryTextChange(searchQuery)) {
            mStatus &= ~QUERY_COMPLETE;
        }
    
public voidsetBadgeDrawable(android.graphics.drawable.Drawable drawable)
Sets the badge drawable that will be shown inside the search bar next to the title.

        mBadgeDrawable = drawable;
        if (null != mSearchBar) {
            mSearchBar.setBadgeDrawable(drawable);
        }
    
public voidsetOnItemClickedListener(android.support.v17.leanback.widget.OnItemClickedListener listener)
Sets an item clicked listener for the results.

param
listener The item clicked listener to be invoked when an item in the search results is clicked.
deprecated
Use {@link #setOnItemViewClickedListener(OnItemViewClickedListener)}

        mOnItemClickedListener = listener;
    
public voidsetOnItemSelectedListener(android.support.v17.leanback.widget.OnItemSelectedListener listener)
Sets an item selection listener for the results.

param
listener The item selection listener to be invoked when an item in the search results is selected.
deprecated
Use {@link #setOnItemViewSelectedListener(OnItemViewSelectedListener)}

        mOnItemSelectedListener = listener;
    
public voidsetOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener listener)
Sets an item clicked listener for the results.

param
listener The item clicked listener to be invoked when an item in the search results is clicked.

        mOnItemViewClickedListener = listener;
    
public voidsetOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener listener)
Sets an item selection listener for the results.

param
listener The item selection listener to be invoked when an item in the search results is selected.

        mOnItemViewSelectedListener = listener;
    
public voidsetSearchQuery(java.lang.String query, boolean submit)
Sets the text of the search query and optionally submits the query. Either {@link SearchResultProvider#onQueryTextChange onQueryTextChange} or {@link SearchResultProvider#onQueryTextSubmit onQueryTextSubmit} will be called on the provider if it is set.

param
query The search query to set.
param
submit Whether to submit the query.

        if (DEBUG) Log.v(TAG, "setSearchQuery " + query + " submit " + submit);
        if (query == null) {
            return;
        }
        mExternalQuery = new ExternalQuery(query, submit);
        applyExternalQuery();
        if (mAutoStartRecognition) {
            mAutoStartRecognition = false;
            mHandler.removeCallbacks(mStartRecognitionRunnable);
        }
    
public voidsetSearchQuery(android.content.Intent intent, boolean submit)
Sets the text of the search query based on the {@link RecognizerIntent#EXTRA_RESULTS} in the given intent, and optionally submit the query. If more than one result is present in the results list, the first will be used.

param
intent Intent received from a speech recognition service.
param
submit Whether to submit the query.

        ArrayList<String> matches = intent.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
        if (matches != null && matches.size() > 0) {
            setSearchQuery(matches.get(0), submit);
        }
    
private voidsetSearchQuery(java.lang.String query)

        mSearchBar.setSearchQuery(query);
    
public voidsetSearchResultProvider(android.support.v17.leanback.app.SearchFragment$SearchResultProvider searchResultProvider)
Set the search provider that is responsible for returning results for the search query.

        if (mProvider != searchResultProvider) {
            mProvider = searchResultProvider;
            onSetSearchResultProvider();
        }
    
public voidsetSpeechRecognitionCallback(android.support.v17.leanback.widget.SpeechRecognitionCallback callback)
Set this callback to have the fragment pass speech recognition requests to the activity rather than using an internal recognizer.

        mSpeechRecognitionCallback = callback;
        if (mSearchBar != null) {
            mSearchBar.setSpeechRecognitionCallback(mSpeechRecognitionCallback);
        }
        if (callback != null) {
            releaseRecognizer();
        }
    
public voidsetTitle(java.lang.String title)
Sets the title string to be be shown in an empty search bar. The title may be placed in a call-to-action, such as "Search title" or "Speak to search title".

        mTitle = title;
        if (null != mSearchBar) {
            mSearchBar.setTitle(title);
        }
    
public voidstartRecognition()
Starts speech recognition. Typical use case is that activity receives onNewIntent() call when user clicks a MIC button. Note that SearchFragment automatically starts speech recognition at first time created, there is no need to call startRecognition() when fragment is created.

        mSearchBar.startRecognition();
    
private voidsubmitQuery(java.lang.String query)

        queryComplete();
        if (null != mProvider) {
            mProvider.onQueryTextSubmit(query);
        }
    
private voidupdateFocus()

        if (mResultAdapter != null && mResultAdapter.size() > 0 &&
                mRowsFragment != null && mRowsFragment.getAdapter() == mResultAdapter) {
            focusOnResults();
        } else {
            mSearchBar.requestFocus();
        }
    
private voidupdateSearchBarNextFocusId()

        if (mSearchBar == null || mResultAdapter == null) {
            return;
        }
        final int viewId = (mResultAdapter.size() == 0 || mRowsFragment == null ||
                mRowsFragment.getVerticalGridView() == null) ? 0 :
                mRowsFragment.getVerticalGridView().getId();
        mSearchBar.setNextFocusDownId(viewId);