Les utilisateurs ont souvent des contenus spécifiques en tête lorsqu'ils utilisent une application multimédia sur leur téléviseur. Si votre application contient un vaste catalogue de contenus, la recherche d'un titre spécifique n'est peut-être pas le moyen le plus efficace pour les utilisateurs de trouver ce qu'ils recherchent. Une interface de recherche peut aider les utilisateurs à accéder au contenu qui les intéresse plus rapidement que lorsque vous naviguez sur le Web.
La bibliothèque Android Leanback fournit un ensemble de classes pour activer une interface de recherche standard dans votre application, qui est cohérente avec d'autres fonctions de recherche sur téléviseur et fournit des fonctionnalités telles que la saisie vocale.
Ce guide explique comment fournir une interface de recherche dans votre application à l'aide des classes de la bibliothèque Support Leanback.
Ajouter une action de recherche
Lorsque vous utilisez la classe BrowseFragment
pour une interface de navigation multimédia, vous pouvez activer une interface de recherche en tant que partie standard de l'interface utilisateur. L'interface de recherche est une icône qui apparaît dans la mise en page lorsque vous définissez View.OnClickListener
sur l'objet BrowseFragment
. L'exemple de code suivant illustre cette technique.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.browse_activity) browseFragment = fragmentManager.findFragmentById(R.id.browse_fragment) as BrowseFragment browseFragment.setOnSearchClickedListener { view -> val intent = Intent(this@BrowseActivity, SearchActivity::class.java) startActivity(intent) } browseFragment.setAdapter(buildAdapter()) }
Java
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.browse_activity); browseFragment = (BrowseFragment) getFragmentManager().findFragmentById(R.id.browse_fragment); ... browseFragment.setOnSearchClickedListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(BrowseActivity.this, SearchActivity.class); startActivity(intent); } }); browseFragment.setAdapter(buildAdapter()); }
Remarque:Vous pouvez définir la couleur de l'icône de recherche à l'aide de la méthode setSearchAffordanceColor(int)
.
Ajouter une entrée de recherche et des résultats
Lorsqu'un utilisateur sélectionne l'icône de recherche, le système appelle une activité de recherche à l'aide de l'intent défini. Pour votre activité de recherche, utilisez une mise en page linéaire contenant un SearchFragment
.
Ce fragment doit également implémenter l'interface SearchFragment.SearchResultProvider
pour afficher les résultats d'une recherche.
L'exemple de code suivant montre comment étendre la classe SearchFragment
pour fournir une interface de recherche et des résultats:
Kotlin
class MySearchFragment : SearchFragment(), SearchFragment.SearchResultProvider { private val rowsAdapter = ArrayObjectAdapter(ListRowPresenter()) private val handler = Handler() private val delayedLoad = SearchRunnable() val resultsAdapter: ObjectAdapter get() { return rowsAdapter } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setSearchResultProvider(this) setOnItemClickedListener(getDefaultItemClickedListener()) } fun onQueryTextChange(newQuery: String): Boolean { rowsAdapter.clear() if (!TextUtils.isEmpty(newQuery)) { delayedLoad.setSearchQuery(newQuery) handler.removeCallbacks(delayedLoad) handler.postDelayed(delayedLoad, SEARCH_DELAY_MS) } return true } fun onQueryTextSubmit(query: String): Boolean { rowsAdapter.clear() if (!TextUtils.isEmpty(query)) { delayedLoad.setSearchQuery(query) handler.removeCallbacks(delayedLoad) handler.postDelayed(delayedLoad, SEARCH_DELAY_MS) } return true } companion object { private val SEARCH_DELAY_MS = 300 } }
Java
public class MySearchFragment extends SearchFragment implements SearchFragment.SearchResultProvider { private static final int SEARCH_DELAY_MS = 300; private ArrayObjectAdapter rowsAdapter; private Handler handler = new Handler(); private SearchRunnable delayedLoad; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); rowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); setSearchResultProvider(this); setOnItemClickedListener(getDefaultItemClickedListener()); delayedLoad = new SearchRunnable(); } @Override public ObjectAdapter getResultsAdapter() { return rowsAdapter; } @Override public boolean onQueryTextChange(String newQuery) { rowsAdapter.clear(); if (!TextUtils.isEmpty(newQuery)) { delayedLoad.setSearchQuery(newQuery); handler.removeCallbacks(delayedLoad); handler.postDelayed(delayedLoad, SEARCH_DELAY_MS); } return true; } @Override public boolean onQueryTextSubmit(String query) { rowsAdapter.clear(); if (!TextUtils.isEmpty(query)) { delayedLoad.setSearchQuery(query); handler.removeCallbacks(delayedLoad); handler.postDelayed(delayedLoad, SEARCH_DELAY_MS); } return true; } }
L'exemple de code précédent est destiné à être utilisé avec une classe SearchRunnable
qui exécute la requête de recherche sur un thread distinct. Cette technique empêche les requêtes potentiellement lentes de bloquer le thread de l'interface utilisateur principal.