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 vos utilisateurs à accéder au contenu qu'ils souhaitent plus rapidement qu'en parcourant le site.
La bibliothèque androidx.leanback fournit un ensemble de classes permettant d'activer une interface de recherche standard dans votre application, cohérente avec les autres fonctions de recherche sur TV et offrant 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 un champ 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 élément 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 et des résultats de recherche:
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 principal de l'interface utilisateur.