Kartenansicht bereitstellen

Bessere Apps mit Compose entwickeln
Mit Jetpack Compose für Android TV OS können Sie mit minimalem Code schöne Benutzeroberflächen erstellen.

In diesem Leitfaden geht es darum, die Kartenansichten für Ihre Media-Elemente zu erstellen und sie im Browse-Fragment mit dem eingestellten Leanback-UI-Toolkit zu präsentieren. Die Implementierung des Katalogbrowsers in einem Browse-Fragment wird im Leitfaden zu Browse-Fragmenten beschrieben.

Die Klasse BaseCardView und ihre Unterklassen zeigen die mit einem Medienelement verknüpften Metadaten an. In dieser Lektion wird die Klasse ImageCardView verwendet, um ein Bild für den Inhalt zusammen mit dem Titel des Media-Elements anzuzeigen.

Weitere Informationen finden Sie in der Beispielimplementierung in der eingestellten Leanback-Beispiel-App.

App-Kartenansicht

Abbildung 1: Die Bildkartenansicht der Leanback-Beispiel-App, wenn sie ausgewählt ist.

Kartenpräsentator erstellen

Ein Presenter generiert Ansichten und bindet Objekte bei Bedarf daran. Im Browse-Fragment, in dem deine App ihre Inhalte für den Nutzer präsentiert, erstellst du ein Presenter für die Inhaltskarten und übergibst es an den Adapter, der die Inhalte auf dem Bildschirm hinzufügt. Im folgenden Code wird CardPresenter im onLoadFinished()-Callback von LoaderManager erstellt:

Kotlin

override fun onLoadFinished(loader: Loader<HashMap<String, List<Movie>>>, data: HashMap<String, List<Movie>>) {
    rowsAdapter = ArrayObjectAdapter(ListRowPresenter())
    val cardPresenter = CardPresenter()

    var i = 0L

    data.entries.forEach { entry ->
        val listRowAdapter = ArrayObjectAdapter(cardPresenter).apply {
            entry.value.forEach { movie ->
                add(movie)
            }
        }

        val header = HeaderItem(i, entry.key)
        i++
        rowsAdapter.add(ListRow(header, listRowAdapter))
    }

    val gridHeader = HeaderItem(i, getString(R.string.more_samples))

    val gridRowAdapter = ArrayObjectAdapter(GridItemPresenter()).apply {
        add(getString(R.string.grid_view))
        add(getString(R.string.error_fragment))
        add(getString(R.string.personal_settings))
    }
    rowsAdapter.add(ListRow(gridHeader, gridRowAdapter))

    adapter = rowsAdapter

    updateRecommendations()
}

Java

@Override
public void onLoadFinished(Loader<HashMap<String, List<Movie>>> arg0,
                           HashMap<String, List<Movie>> data) {

    rowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
    CardPresenter cardPresenter = new CardPresenter();

    int i = 0;

    for (Map.Entry<String, List<Movie>> entry : data.entrySet()) {
        ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
        List<Movie> list = entry.getValue();

        for (int j = 0; j < list.size(); j++) {
            listRowAdapter.add(list.get(j));
        }
        HeaderItem header = new HeaderItem(i, entry.getKey());
        i++;
        rowsAdapter.add(new ListRow(header, listRowAdapter));
    }

    HeaderItem gridHeader = new HeaderItem(i, getString(R.string.more_samples));

    GridItemPresenter gridPresenter = new GridItemPresenter();
    ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridPresenter);
    gridRowAdapter.add(getString(R.string.grid_view));
    gridRowAdapter.add(getString(R.string.error_fragment));
    gridRowAdapter.add(getString(R.string.personal_settings));
    rowsAdapter.add(new ListRow(gridHeader, gridRowAdapter));

    setAdapter(rowsAdapter);

    updateRecommendations();
}

Kartenansicht erstellen

In diesem Schritt erstellen Sie den Karten-Presenter mit einem View-Holder für die Kartenansicht, in der Ihre Media-Inhalte beschrieben werden. Beachten Sie, dass jeder Moderator nur einen Ansichtstyp erstellen darf. Wenn Sie zwei Arten von Kartenansichten haben, benötigen Sie zwei Kartenpräsentatoren.

Implementieren Sie im Presenter einen onCreateViewHolder()-Callback, der einen View-Holder erstellt, mit dem ein Inhaltselement angezeigt werden kann:

Kotlin

private const val CARD_WIDTH = 313
private const val CARD_HEIGHT = 176

class CardPresenter : Presenter() {

    private lateinit var mContext: Context
    private lateinit var defaultCardImage: Drawable

    override fun onCreateViewHolder(parent: ViewGroup): Presenter.ViewHolder {
        mContext = parent.context
        defaultCardImage = mContext.resources.getDrawable(R.drawable.movie)
        ...

Java

@Override
public class CardPresenter extends Presenter {

    private Context context;
    private static int CARD_WIDTH = 313;
    private static int CARD_HEIGHT = 176;
    private Drawable defaultCardImage;

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent) {
        context = parent.getContext();
        defaultCardImage = context.getResources().getDrawable(R.drawable.movie);
...

Erstellen Sie in der onCreateViewHolder()-Methode eine Kartenansicht für Inhaltselemente. Im folgenden Beispiel wird ein ImageCardView verwendet.

Wenn eine Karte ausgewählt wird, wird sie standardmäßig vergrößert. Wenn Sie der ausgewählten Karte eine andere Farbe zuweisen möchten, rufen Sie setSelected() wie hier gezeigt auf:

Kotlin

    ...
    val cardView = object : ImageCardView(context) {
        override fun setSelected(selected: Boolean) {
            val selected_background = context.resources.getColor(R.color.detail_background)
            val default_background = context.resources.getColor(R.color.default_background)
            val color = if (selected) selected_background else default_background
            findViewById<View>(R.id.info_field).setBackgroundColor(color)
            super.setSelected(selected)
        }
    }
    ...

Java

...
    ImageCardView cardView = new ImageCardView(context) {
        @Override
        public void setSelected(boolean selected) {
            int selected_background = context.getResources().getColor(R.color.detail_background);
            int default_background = context.getResources().getColor(R.color.default_background);
            int color = selected ? selected_background : default_background;
            findViewById(R.id.info_field).setBackgroundColor(color);
            super.setSelected(selected);
        }
    };
...

Wenn der Nutzer Ihre App öffnet, werden im Presenter.ViewHolder die CardView-Objekte für Ihre Inhaltselemente angezeigt. Sie müssen diese festlegen, damit der Fokus vom D-Pad-Controller empfangen wird. Rufen Sie dazu setFocusable(true) und setFocusableInTouchMode(true) auf, wie im folgenden Code gezeigt:

Kotlin

    ...
    cardView.isFocusable = true
    cardView.isFocusableInTouchMode = true
    return ViewHolder(cardView)
}

Java

...
    cardView.setFocusable(true);
    cardView.setFocusableInTouchMode(true);
    return new ViewHolder(cardView);
}

Wenn der Nutzer ImageCardView auswählt, wird der Textbereich mit der von Ihnen angegebenen Hintergrundfarbe maximiert (siehe Abbildung 1).