Udostępnianie widoku kart

Twórz lepsze aplikacje dzięki Compose
Twórz piękne interfejsy użytkownika przy użyciu minimalnej ilości kodu dzięki Jetpack Compose na Androida TV.

Ten przewodnik koncentruje się na tworzeniu widoków kart dla elementów multimedialnych i prezentowaniu ich we fragmencie przeglądania za pomocą wycofanego zestawu narzędzi Leanback UI. Implementacja przeglądarki katalogu we fragmencie przeglądania jest szczegółowo opisana w przewodniku po fragmencie przeglądania.

Klasa BaseCardView i jej podklasy wyświetlają metadane powiązane z elementem multimedialnym. Klasa ImageCardView używana w tej lekcji wyświetla obraz treści wraz z tytułem elementu multimedialnego.

Zobacz też przykładową implementację w wycofanej przykładowej aplikacji Leanback .

Widok karty aplikacji

Rysunek 1. Widok karty obrazu w przykładowej aplikacji Leanback po wybraniu.

Tworzenie prezentera kart

Presenter generuje widoki i wiąże z nimi obiekty na żądanie. We fragmencie przeglądania, w którym aplikacja prezentuje użytkownikowi swoje treści, tworzysz Presenter dla kart treści i przekazujesz go do adaptera, który dodaje treści do ekranu. W poniższym kodzie CardPresenter jest tworzony w wywołaniu zwrotnym onLoadFinished() klasy LoaderManager:

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

Tworzenie widoku karty

W tym kroku tworzysz prezentera kart z uchwytem widoku dla widoku karty, który opisuje elementy treści multimedialnych. Pamiętaj, że każdy prezenter musi tworzyć tylko 1 typ widoku. Jeśli masz 2 typy widoków kart, potrzebujesz 2 prezenterów kart.

W Presenter zaimplementuj wywołanie zwrotne onCreateViewHolder(), które tworzy uchwyt widoku, którego można użyć do wyświetlania elementu treści:

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);
...

W metodzie onCreateViewHolder() utwórz widok karty dla elementów treści. W tym przykładzie używamy klasy ImageCardView.

Gdy karta jest wybrana, domyślnie powiększa się. Jeśli chcesz przypisać inny kolor do wybranej karty, wywołaj metodę setSelected() w sposób pokazany poniżej:

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

Gdy użytkownik otworzy aplikację, Presenter.ViewHolder wyświetli obiekty CardView dla elementów treści. Aby można było ustawić na nich fokus za pomocą kontrolera pad kierunkowy, musisz ustawić te obiekty, wywołując metody setFocusable(true) i setFocusableInTouchMode(true), jak pokazano w poniższym kodzie:

Kotlin

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

Java

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

Gdy użytkownik wybierze ImageCardView, rozwinie się ona, aby odsłonić obszar tekstowy z określonym przez Ciebie kolorem tła, jak pokazano na rysunku 1.