TV uygulamalarında arama

Kullanıcıların, TV'de bir medya uygulaması kullanırken aklında genellikle belirli bir içerik vardır. Uygulamanız geniş bir içerik kataloğu içeriyorsa belirli bir başlığa göz atmak, kullanıcıların aradıklarını bulmaları için en etkili yol olmayabilir. Arama arayüzü, kullanıcılarınızın istedikleri içeriğe göz atmaktan daha hızlı olmalarına yardımcı olabilir.

Leanback androidx kitaplığı, uygulamanızda TV'deki diğer arama işlevleriyle tutarlı olan ve ses girişi gibi özellikler sunan standart bir arama arayüzünü etkinleştirmek için bir dizi sınıf sağlar.

Bu kılavuzda, Leanback desteği kütüphane sınıflarını kullanarak uygulamanızda bir arama arayüzünün nasıl sağlanacağı açıklanmaktadır.

Arama işlemi ekleyin

Medya tarama arayüzü için BrowseFragment sınıfını kullandığınızda, arama arayüzünü kullanıcı arayüzünün standart bir parçası olarak etkinleştirebilirsiniz. Arama arayüzü, BrowseFragment nesnesinde View.OnClickListener özelliğini ayarladığınızda düzende görünen bir simgedir. Aşağıdaki örnek kod bu tekniği gösterir.

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

Not: setSearchAffordanceColor(int) yöntemini kullanarak arama simgesinin rengini ayarlayabilirsiniz.

Arama girişi ve sonuçları ekleme

Bir kullanıcı arama simgesini seçtiğinde, sistem tanımlı amacı kullanarak bir arama etkinliği çağırır. Arama etkinliğiniz için SearchFragment içeren doğrusal bir düzen kullanın. Bu parça, bir aramanın sonuçlarını görüntülemek için SearchFragment.SearchResultProvider arayüzünü de uygulamalıdır.

Aşağıdaki kod örneğinde, bir arama arayüzü ve sonuç sağlamak için SearchFragment sınıfının nasıl genişletileceği gösterilmektedir:

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

Önceki örnek kodun, arama sorgusunu ayrı bir iş parçacığında çalıştıran bir SearchRunnable sınıfıyla kullanılması amaçlanmıştır. Bu teknik, potansiyel olarak yavaş çalışan sorguların ana kullanıcı arayüzü iş parçacığını engellemesini önler.