Người dùng thường có sẵn nội dung cụ thể khi sử dụng ứng dụng đa phương tiện trên TV. Nếu ứng dụng của bạn có một danh mục nội dung lớn, thì việc duyệt tìm một tiêu đề cụ thể có thể không phải là cách hiệu quả nhất để người dùng tìm thấy nội dung họ đang tìm kiếm. Giao diện tìm kiếm có thể giúp người dùng tìm thấy nội dung họ muốn nhanh hơn so với việc duyệt web.
Thư viện androidx.leanback cung cấp một tập hợp các lớp để cho phép giao diện tìm kiếm tiêu chuẩn trong ứng dụng của bạn, nhất quán với các chức năng tìm kiếm khác trên TV và cung cấp các tính năng như nhập liệu bằng giọng nói.
Hướng dẫn này thảo luận về cách cung cấp giao diện tìm kiếm trong ứng dụng bằng cách sử dụng các lớp thư viện hỗ trợ Leanback.
Thêm thao tác tìm kiếm
Khi bạn sử dụng lớp BrowseFragment cho giao diện duyệt phương tiện, bạn có thể bật giao diện tìm kiếm như một phần tiêu chuẩn của giao diện người dùng. Giao diện tìm kiếm là một biểu tượng xuất hiện trong bố cục khi bạn đặt View.OnClickListener trên đối tượng BrowseFragment. Đoạn mã mẫu sau đây minh họa kỹ thuật này.
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()); }
Lưu ý: Bạn có thể đặt màu cho biểu tượng tìm kiếm bằng phương thức setSearchAffordanceColor(int).
Thêm một đầu vào tìm kiếm và kết quả
Khi người dùng chọn biểu tượng tìm kiếm, hệ thống sẽ gọi một hoạt động tìm kiếm bằng cách sử dụng ý định đã xác định. Đối với hoạt động tìm kiếm, hãy sử dụng một bố cục tuyến tính chứa SearchFragment.
Mảnh này cũng phải triển khai giao diện SearchFragment.SearchResultProvider để hiển thị kết quả của một lượt tìm kiếm.
Mẫu mã sau đây cho thấy cách mở rộng lớp SearchFragment để cung cấp giao diện tìm kiếm và kết quả:
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; } }
Mã ví dụ trước đó được dùng với một lớp SearchRunnable chạy truy vấn tìm kiếm trên một luồng riêng biệt. Kỹ thuật này giúp ngăn chặn các truy vấn có khả năng chạy chậm làm tắc nghẽn luồng giao diện người dùng chính.