Quando utilizzano un'app multimediale sulla TV, gli utenti hanno spesso in mente contenuti specifici. Se la tua app contiene un ampio catalogo di contenuti, la ricerca di un titolo specifico potrebbe non essere il modo più efficiente per gli utenti di trovare ciò che stanno cercando. Un'interfaccia di ricerca può aiutare gli utenti a trovare i contenuti che vogliono più rapidamente rispetto alla navigazione.
La libreria androidx.leanback fornisce un insieme di classi per abilitare un'interfaccia di ricerca standard all'interno dell'app, coerente con altre funzioni di ricerca sulla TV e che fornisce funzionalità come l'input vocale.
Questa guida spiega come fornire un'interfaccia di ricerca nella tua app utilizzando le classi della libreria di supporto Leanback.
Aggiungere un'azione di ricerca
Quando utilizzi la classe BrowseFragment per un'interfaccia di navigazione tra i contenuti multimediali, puoi abilitare un'interfaccia di ricerca come parte standard dell'interfaccia utente. L'interfaccia di ricerca è un'icona che viene visualizzata nel layout quando imposti View.OnClickListener sull'oggetto BrowseFragment. Il seguente codice campione illustra questa tecnica.
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()); }
Nota: puoi impostare il colore dell'icona di ricerca utilizzando il
setSearchAffordanceColor(int)
metodo.
Aggiungere un input di ricerca e risultati
Quando un utente seleziona l'icona di ricerca, il sistema richiama un'attività di ricerca utilizzando l'
intent definito. Per l'attività di ricerca, utilizza un layout lineare contenente un
SearchFragment.
Questo frammento deve anche implementare l'interfaccia SearchFragment.SearchResultProvider
per visualizzare i risultati di una ricerca.
Il seguente esempio di codice mostra come estendere la classe SearchFragment per fornire un'interfaccia di ricerca e risultati:
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; } }
Il codice di esempio precedente è progettato per essere utilizzato con una classe SearchRunnable
che esegue la query di ricerca su un thread separato. Questa tecnica impedisce alle query potenzialmente lente
di bloccare il thread dell'interfaccia utente principale.