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