page.title=Searching within TV Apps page.tags=tv, leanback helpoutsWidget=true trainingnavtop=true @jd:body

This lesson teaches you to

  1. Add a Search Action
  2. Add Search Input and Results

Users frequently have specific content in mind when using a media app on TV. If your app contains a large catalog of content, browsing for a specific title may not be the most efficient way for users to find what they are looking for. A search interface can help your users get to the content they want faster than browsing.

The Leanback support library provides a set of classes to enable a standard search interface within your app that is consistent with other search functions on TV and provides features such as voice input.

This lesson discusses how to provide a search interface in your app using Leanback support library classes.

Add a Search Action

When you use the {@link android.support.v17.leanback.app.BrowseFragment} class for a media browsing interface, you can enable a search interface as a standard part of the user interface. The search interface is an icon that appears in the layout when you set {@link android.view.View.OnClickListener} on the {@link android.support.v17.leanback.app.BrowseFragment} object. The following sample code demonstrates this technique.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.browse_activity);

    mBrowseFragment = (BrowseFragment)
            getFragmentManager().findFragmentById(R.id.browse_fragment);

    ...

    mBrowseFragment.setOnSearchClickedListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(BrowseActivity.this, SearchActivity.class);
            startActivity(intent);
        }
    });

    mBrowseFragment.setAdapter(buildAdapter());
}

Note: You can set the color of the search icon using the {@link android.support.v17.leanback.app.BrowseFragment#setSearchAffordanceColor}.

Add a Search Input and Results

When a user selects the search icon, the system invokes a search activity via the defined intent. Your search activity should use a linear layout containing a {@link android.support.v17.leanback.app.SearchFragment}. This fragment must also implement the {@link android.support.v17.leanback.app.SearchFragment.SearchResultProvider} interface in order to display the results of a search.

The following code sample shows how to extend the {@link android.support.v17.leanback.app.SearchFragment} class to provide a search interface and results:

public class MySearchFragment extends SearchFragment
        implements SearchFragment.SearchResultProvider {

    private static final int SEARCH_DELAY_MS = 300;
    private ArrayObjectAdapter mRowsAdapter;
    private Handler mHandler = new Handler();
    private SearchRunnable mDelayedLoad;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
        setSearchResultProvider(this);
        setOnItemClickedListener(getDefaultItemClickedListener());
        mDelayedLoad = new SearchRunnable();
    }

    @Override
    public ObjectAdapter getResultsAdapter() {
        return mRowsAdapter;
    }

    @Override
    public boolean onQueryTextChange(String newQuery) {
        mRowsAdapter.clear();
        if (!TextUtils.isEmpty(newQuery)) {
            mDelayedLoad.setSearchQuery(newQuery);
            mHandler.removeCallbacks(mDelayedLoad);
            mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
        }
        return true;
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        mRowsAdapter.clear();
        if (!TextUtils.isEmpty(query)) {
            mDelayedLoad.setSearchQuery(query);
            mHandler.removeCallbacks(mDelayedLoad);
            mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
        }
        return true;
    }
}

The example code shown above is meant to be used with a separate {@code SearchRunnable} class that runs the search query on a separate thread. This technique keeps potentially slow-running queries from blocking the main user interface thread.