Melakukan penelusuran di dalam aplikasi TV

Pengguna sering mengangankan konten tertentu saat menggunakan aplikasi media di TV. Jika aplikasi Anda berisi katalog konten yang besar, menelusuri judul tertentu mungkin bukan cara paling efisien untuk pengguna untuk menemukan apa yang mereka cari. Antarmuka penelusuran dapat membantu pengguna untuk konten yang mereka inginkan lebih cepat daripada menjelajah.

Library androidx.Lean menyediakan kumpulan class untuk mengaktifkan antarmuka penelusuran standar dalam aplikasi Anda yang konsisten dengan fungsi penelusuran lainnya di TV dan menyediakan fitur seperti input suara.

Panduan ini membahas cara menyediakan antarmuka penelusuran di aplikasi Anda menggunakan dukungan Leanback library.

Menambahkan tindakan penelusuran

Saat Anda menggunakan class BrowseFragment untuk media sebagai antarmuka penelusuran, Anda dapat mengaktifkan antarmuka penelusuran sebagai bagian standar dari dalam antarmuka berbasis web yang sederhana. Antarmuka penelusuran adalah ikon yang muncul di tata letak saat Anda menyetel View.OnClickListener pada BrowseFragment . Contoh kode berikut mendemonstrasikan teknik ini.

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());
}

Catatan: Anda dapat menetapkan warna ikon penelusuran menggunakan setSearchAffordanceColor(int) .

Menambahkan input penelusuran dan hasil

Bila pengguna memilih ikon penelusuran, sistem akan memanggil aktivitas penelusuran menggunakan intent yang ditentukan. Untuk aktivitas penelusuran Anda, gunakan tata letak linier yang berisi SearchFragment. Fragmen ini juga harus mengimplementasikan SearchFragment.SearchResultProvider untuk menampilkan hasil penelusuran.

Contoh kode berikut menunjukkan cara memperluas class SearchFragment untuk menyediakan antarmuka dan hasil penelusuran:

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;
    }
}

Kode contoh sebelumnya dimaksudkan untuk digunakan dengan class SearchRunnable yang menjalankan kueri pencarian pada utas terpisah. Teknik ini membuat video tetap berjalan lambat agar tidak memblokir thread antarmuka pengguna utama.