在 TV 应用内进行搜索
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
在电视上使用媒体应用时,用户通常会想到一些具体内容。如果您的应用包含
因为浏览具体游戏可能并不是
找到他们所需的内容搜索界面可以帮助您的用户找到
比浏览更快的内容。
androidx.leanback 库提供了一组类来启用标准搜索界面
以便与电视上的其他搜索功能保持一致,并提供
语音输入。
本指南介绍如何在您的应用中使用 Leanback 支持提供搜索界面
库类。
添加搜索操作
当您对媒体使用 BrowseFragment
类时
您可以启用搜索界面作为用户
界面。搜索界面是当您在 BrowseFragment
上设置 View.OnClickListener
时,布局中显示的一个图标
对象。以下示例代码演示了这种方法。
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());
}
注意:您可以使用
setSearchAffordanceColor(int)
方法。
添加搜索输入和结果
当用户选择搜索图标时,系统会使用
定义 intent。对于搜索 activity,请使用包含
SearchFragment
。
此 fragment 还必须实现 SearchFragment.SearchResultProvider
界面。
以下代码示例展示了如何扩展 SearchFragment
类
提供搜索界面和结果:
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;
}
}
前面的示例代码应当与 SearchRunnable
类一起使用
。此方法可能会导致运行缓慢
以免阻塞主要的用户界面线程
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-27。
[null,null,["最后更新时间 (UTC):2025-07-27。"],[],[],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."]]