TV uygulamalarında arama

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

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

Bu kılavuzda, Leanback destek kitaplığı 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 göz atma 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 nesnesi üzerinde View.OnClickListener değerini ayarladığınızda düzende görünen bir simgedir. Aşağıdaki örnek kod bu tekniği göstermektedir.

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: Arama simgesinin rengini setSearchAffordanceColor(int) yöntemini kullanarak ayarlayabilirsiniz.

Arama girişi ve sonuç ekleyin

Bir kullanıcı arama simgesini seçtiğinde, sistem tanımlanan amacı kullanarak bir arama etkinliği başlatı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, arama arayüzü ve sonuçlar 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, yavaş olabilecek sorguların ana kullanıcı arayüzü iş parçacığını engellemesini önler.