Cerca nelle app per TV
Mantieni tutto organizzato con le raccolte
Salva e classifica i contenuti in base alle tue preferenze.
Gli utenti spesso hanno in mente contenuti specifici quando utilizzano un'app multimediale sulla TV. Se l'app contiene
un ampio catalogo di contenuti, cercare un titolo specifico potrebbe non essere il modo più efficiente
per consentire agli utenti di trovare quello che cercano. Un'interfaccia di ricerca può aiutare gli utenti a raggiungere
i contenuti che vogliono più velocemente di quanto non siano sfogliati.
La libreria androidx.leanback fornisce un insieme di classi per attivare un'interfaccia di ricerca standard.
all'interno dell'app che siano coerenti con altre funzioni di ricerca sulla TV e offrono funzionalità come
input vocale.
Questa guida illustra come fornire un'interfaccia di ricerca nella tua app utilizzando il supporto di Leanback
corsi in biblioteca.
Aggiungi un'azione di ricerca
Quando utilizzi il corso BrowseFragment
per un contenuto multimediale
di navigazione, puoi attivare un'interfaccia di ricerca come parte standard
a riga di comando. L'interfaccia di ricerca è un'icona che viene visualizzata nel layout quando imposti View.OnClickListener
in BrowseFragment
. Il seguente codice di esempio 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)
.
Aggiungi un input di ricerca e risultati
Quando un utente seleziona l'icona di ricerca, il sistema richiama un'attività di ricerca utilizzando il metodo
un intento definito. Per la tua attività di ricerca, utilizza un layout lineare contenente un
SearchFragment
.
Questo frammento deve anche implementare 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 deve essere utilizzato con una classe SearchRunnable
che esegue la query di ricerca su un thread separato. Questa tecnica continua a funzionare lentamente
delle query non blocchino il thread principale dell'interfaccia utente.
I campioni di contenuti e codice in questa pagina sono soggetti alle licenze descritte nella Licenza per i contenuti. Java e OpenJDK sono marchi o marchi registrati di Oracle e/o delle sue società consociate.
Ultimo aggiornamento 2025-07-27 UTC.
[[["Facile da capire","easyToUnderstand","thumb-up"],["Il problema è stato risolto","solvedMyProblem","thumb-up"],["Altra","otherUp","thumb-up"]],[["Mancano le informazioni di cui ho bisogno","missingTheInformationINeed","thumb-down"],["Troppo complicato/troppi passaggi","tooComplicatedTooManySteps","thumb-down"],["Obsoleti","outOfDate","thumb-down"],["Problema di traduzione","translationIssue","thumb-down"],["Problema relativo a esempi/codice","samplesCodeIssue","thumb-down"],["Altra","otherDown","thumb-down"]],["Ultimo aggiornamento 2025-07-27 UTC."],[],[],null,["# Search within TV apps\n\nUsers frequently have specific content in mind when using a media app on TV. If your app contains\na large catalog of content, browsing for a specific title might not be the most efficient way for\nusers to find what they are looking for. A search interface can help your users get to the\ncontent they want faster than browsing.\n\n\nThe [androidx.leanback library](/training/tv/get-started/create#leanback) provides a set of classes to enable a standard search interface\nwithin your app that is consistent with other search functions on TV and provides features like\nvoice input.\n\n\nThis guide discusses how to provide a search interface in your app using Leanback support\nlibrary classes.\n\nAdd a search action\n-------------------\n\n\nWhen you use the [BrowseFragment](/reference/androidx/leanback/app/BrowseFragment) class for a media\nbrowsing interface, you can enable a search interface as a standard part of the user\ninterface. The search interface is an icon that appears in the layout when you set [View.OnClickListener](/reference/android/view/View.OnClickListener) on the `BrowseFragment`\nobject. The following sample code demonstrates this technique. \n\n### Kotlin\n\n```kotlin\noverride fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n setContentView(R.layout.browse_activity)\n browseFragment = fragmentManager.findFragmentById(R.id.browse_fragment) as BrowseFragment\n browseFragment.setOnSearchClickedListener { view -\u003e\n val intent = Intent(this@BrowseActivity, SearchActivity::class.java)\n startActivity(intent)\n }\n\n browseFragment.setAdapter(buildAdapter())\n}\n```\n\n### Java\n\n```java\n@Override\npublic void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n setContentView(R.layout.browse_activity);\n\n browseFragment = (BrowseFragment)\n getFragmentManager().findFragmentById(R.id.browse_fragment);\n\n ...\n\n browseFragment.setOnSearchClickedListener(new View.OnClickListener() {\n @Override\n public void onClick(View view) {\n Intent intent = new Intent(BrowseActivity.this, SearchActivity.class);\n startActivity(intent);\n }\n });\n\n browseFragment.setAdapter(buildAdapter());\n}\n```\n\n\n**Note:** You can set the color of the search icon using the\n[setSearchAffordanceColor(int)](/reference/androidx/leanback/app/BrandedFragment#setSearchAffordanceColor(int))\nmethod.\n\nAdd a search input and results\n------------------------------\n\n\nWhen a user selects the search icon, the system invokes a search activity using the\ndefined intent. For your search activity, use a linear layout containing a\n[SearchFragment](/reference/androidx/leanback/app/SearchFragment).\nThis fragment must also implement the [SearchFragment.SearchResultProvider](/reference/androidx/leanback/app/SearchFragment.SearchResultProvider)\ninterface to display the results of a search.\n\n\nThe following code sample shows how to extend the `SearchFragment` class\nto provide a search interface and results: \n\n### Kotlin\n\n```kotlin\nclass MySearchFragment : SearchFragment(), SearchFragment.SearchResultProvider {\n private val rowsAdapter = ArrayObjectAdapter(ListRowPresenter())\n private val handler = Handler()\n private val delayedLoad = SearchRunnable()\n\n val resultsAdapter: ObjectAdapter\n get() {\n return rowsAdapter\n }\n\n override fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n setSearchResultProvider(this)\n setOnItemClickedListener(getDefaultItemClickedListener())\n }\n\n fun onQueryTextChange(newQuery: String): Boolean {\n rowsAdapter.clear()\n if (!TextUtils.isEmpty(newQuery)) {\n delayedLoad.setSearchQuery(newQuery)\n handler.removeCallbacks(delayedLoad)\n handler.postDelayed(delayedLoad, SEARCH_DELAY_MS)\n }\n return true\n }\n\n fun onQueryTextSubmit(query: String): Boolean {\n rowsAdapter.clear()\n if (!TextUtils.isEmpty(query)) {\n delayedLoad.setSearchQuery(query)\n handler.removeCallbacks(delayedLoad)\n handler.postDelayed(delayedLoad, SEARCH_DELAY_MS)\n }\n return true\n }\n\n companion object {\n private val SEARCH_DELAY_MS = 300\n }\n}\n```\n\n### Java\n\n```java\npublic class MySearchFragment extends SearchFragment\n implements SearchFragment.SearchResultProvider {\n\n private static final int SEARCH_DELAY_MS = 300;\n private ArrayObjectAdapter rowsAdapter;\n private Handler handler = new Handler();\n private SearchRunnable delayedLoad;\n\n @Override\n public void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n\n rowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());\n setSearchResultProvider(this);\n setOnItemClickedListener(getDefaultItemClickedListener());\n delayedLoad = new SearchRunnable();\n }\n\n @Override\n public ObjectAdapter getResultsAdapter() {\n return rowsAdapter;\n }\n\n @Override\n public boolean onQueryTextChange(String newQuery) {\n rowsAdapter.clear();\n if (!TextUtils.isEmpty(newQuery)) {\n delayedLoad.setSearchQuery(newQuery);\n handler.removeCallbacks(delayedLoad);\n handler.postDelayed(delayedLoad, SEARCH_DELAY_MS);\n }\n return true;\n }\n\n @Override\n public boolean onQueryTextSubmit(String query) {\n rowsAdapter.clear();\n if (!TextUtils.isEmpty(query)) {\n delayedLoad.setSearchQuery(query);\n handler.removeCallbacks(delayedLoad);\n handler.postDelayed(delayedLoad, SEARCH_DELAY_MS);\n }\n return true;\n }\n}\n```\n\n\nThe previous example code is meant to be used with a `SearchRunnable` class\nthat runs the search query on a separate thread. This technique keeps potentially slow-running\nqueries from blocking the main user interface thread."]]