In TV-Apps suchen

Nutzer haben häufig bestimmte Inhalte im Kopf, wenn sie eine Medien-App auf dem Fernseher verwenden. Wenn Ihre App Folgendes enthält: ist die Suche nach einem bestimmten Titel möglicherweise nicht die effizienteste Methode, finden, wonach sie suchen. Eine Suchoberfläche kann Ihren Nutzern helfen, die schneller nach den gewünschten Inhalten suchen.

Die androidx.leanback-Bibliothek bietet eine Reihe von Klassen, die eine Standardsuchoberfläche ermöglichen. die mit anderen Suchfunktionen auf dem Fernseher übereinstimmt und Funktionen wie Spracheingabe verwenden.

In diesem Leitfaden wird erläutert, wie Sie mithilfe der Leanback-Unterstützung eine Suchoberfläche in Ihrer App bereitstellen können. Bibliotheksklassen.

Suchaktion hinzufügen

Wenn Sie die Klasse BrowseFragment für ein Medienobjekt verwenden können Sie standardmäßig eine Suchoberfläche . Die Suchoberfläche ist ein Symbol, das im Layout angezeigt wird, wenn du View.OnClickListener auf dem BrowseFragment festlegst -Objekt enthält. Der folgende Beispielcode veranschaulicht diese Technik.

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

Hinweis:Du kannst die Farbe des Suchsymbols über die Schaltfläche setSearchAffordanceColor(int) .

Sucheingaben und -ergebnisse hinzufügen

Wenn ein Nutzer das Suchsymbol auswählt, ruft das System mithilfe der Funktion Intent definiert. Verwenden Sie für Ihre Suchaktivitäten ein lineares Layout mit einem SearchFragment Dieses Fragment muss auch das SearchFragment.SearchResultProvider implementieren. um die Ergebnisse einer Suche anzuzeigen.

Das folgende Codebeispiel zeigt, wie die SearchFragment-Klasse erweitert wird. um eine Suchoberfläche und Suchergebnisse bereitzustellen:

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

Der vorherige Beispielcode soll mit einer SearchRunnable-Klasse verwendet werden. der die Suchanfrage in einem separaten Thread ausführt. Dieses Verfahren führt möglicherweise blockieren den Hauptthread der Benutzeroberfläche.