Home | History | Annotate | Download | only in discovery
      1 page.title=Searching within TV Apps
      2 page.tags=tv, leanback
      3 helpoutsWidget=true
      4 
      5 trainingnavtop=true
      6 
      7 @jd:body
      8 
      9 <div id="tb-wrapper">
     10 <div id="tb">
     11   <h2>This lesson teaches you to</h2>
     12   <ol>
     13     <li><a href="#add-search-action">Add a Search Action</a></li>
     14     <li><a href="#add-search-ui">Add Search Input and Results</a></li>
     15   </ol>
     16 
     17 </div>
     18 </div>
     19 
     20 
     21 <p>
     22   Users frequently have specific content in mind when using a media app on TV. If your app contains
     23   a large catalog of content, browsing for a specific title may not be the most efficient way for
     24   users to find what they are looking for. A search interface can help your users get to the
     25   content they want faster than browsing.
     26 </p>
     27 
     28 <p>
     29   The <a href="{@docRoot}tools/support-library/features.html#v17-leanback">Leanback support
     30   library</a> provides a set of classes to enable a standard search interface within your app that
     31   is consistent with other search functions on TV and provides features such as voice input.
     32 </p>
     33 
     34 <p>
     35   This lesson discusses how to provide a search interface in your app using Leanback support
     36   library classes.
     37 </p>
     38 
     39 
     40 <h2 id="add-search-action">Add a Search Action</h2>
     41 
     42 <p>
     43   When you use the {@link android.support.v17.leanback.app.BrowseFragment} class for a media
     44   browsing interface, you can enable a search interface as a standard part of the user
     45   interface. The search interface is an icon that appears in the layout when you set {@link
     46   android.view.View.OnClickListener} on the {@link android.support.v17.leanback.app.BrowseFragment}
     47   object. The following sample code demonstrates this technique.
     48 </p>
     49 
     50 <pre>
     51 &#64;Override
     52 public void onCreate(Bundle savedInstanceState) {
     53     super.onCreate(savedInstanceState);
     54     setContentView(R.layout.browse_activity);
     55 
     56     mBrowseFragment = (BrowseFragment)
     57             getFragmentManager().findFragmentById(R.id.browse_fragment);
     58 
     59     ...
     60 
     61     mBrowseFragment.setOnSearchClickedListener(new View.OnClickListener() {
     62         &#64;Override
     63         public void onClick(View view) {
     64             Intent intent = new Intent(BrowseActivity.this, SearchActivity.class);
     65             startActivity(intent);
     66         }
     67     });
     68 
     69     mBrowseFragment.setAdapter(buildAdapter());
     70 }
     71 </pre>
     72 
     73 <p class="note">
     74   <strong>Note:</strong> You can set the color of the search icon using the
     75   {@link android.support.v17.leanback.app.BrowseFragment#setSearchAffordanceColor}.
     76 </p>
     77 
     78 
     79 <h2 id="add-search-ui">Add a Search Input and Results</h2>
     80 
     81 <p>
     82   When a user selects the search icon, the system invokes a search activity via the defined intent.
     83   Your search activity should use a linear layout containing a {@link
     84   android.support.v17.leanback.app.SearchFragment}. This fragment must also implement the {@link
     85   android.support.v17.leanback.app.SearchFragment.SearchResultProvider} interface in order to
     86   display the results of a search.
     87 </p>
     88 
     89 <p>
     90   The following code sample shows how to extend the {@link
     91   android.support.v17.leanback.app.SearchFragment} class to provide a search interface and results:
     92 </p>
     93 
     94 <pre>
     95 public class MySearchFragment extends SearchFragment
     96         implements SearchFragment.SearchResultProvider {
     97 
     98     private static final int SEARCH_DELAY_MS = 300;
     99     private ArrayObjectAdapter mRowsAdapter;
    100     private Handler mHandler = new Handler();
    101     private SearchRunnable mDelayedLoad;
    102 
    103     &#64;Override
    104     public void onCreate(Bundle savedInstanceState) {
    105         super.onCreate(savedInstanceState);
    106 
    107         mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
    108         setSearchResultProvider(this);
    109         setOnItemClickedListener(getDefaultItemClickedListener());
    110         mDelayedLoad = new SearchRunnable();
    111     }
    112 
    113     &#64;Override
    114     public ObjectAdapter getResultsAdapter() {
    115         return mRowsAdapter;
    116     }
    117 
    118     &#64;Override
    119     public boolean onQueryTextChange(String newQuery) {
    120         mRowsAdapter.clear();
    121         if (!TextUtils.isEmpty(newQuery)) {
    122             mDelayedLoad.setSearchQuery(newQuery);
    123             mHandler.removeCallbacks(mDelayedLoad);
    124             mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
    125         }
    126         return true;
    127     }
    128 
    129     &#64;Override
    130     public boolean onQueryTextSubmit(String query) {
    131         mRowsAdapter.clear();
    132         if (!TextUtils.isEmpty(query)) {
    133             mDelayedLoad.setSearchQuery(query);
    134             mHandler.removeCallbacks(mDelayedLoad);
    135             mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
    136         }
    137         return true;
    138     }
    139 }
    140 </pre>
    141 
    142 <p>
    143   The example code shown above is meant to be used with a separate {@code SearchRunnable} class
    144   that runs the search query on a separate thread. This technique keeps potentially slow-running
    145   queries from blocking the main user interface thread.
    146 </p>
    147