Fornire una visualizzazione a schede

Crea contenuti migliori con Compose
Crea UI accattivanti con un codice minimo utilizzando Jetpack Compose per Android TV OS.

Questa guida si concentra sulla creazione delle visualizzazioni delle schede per gli elementi multimediali e sulla loro presentazione nel frammento di navigazione utilizzando il toolkit UI Leanback ritirato. L'implementazione del browser del catalogo in un frammento di navigazione è descritta in dettaglio nella guida Frammento di navigazione.

La classe BaseCardView e le relative sottoclassi mostrano i metadati associati a un elemento multimediale. La classe ImageCardView utilizzata in questa lezione mostra un'immagine per i contenuti insieme al titolo dell'elemento multimediale.

Consulta anche l'implementazione di esempio nell' app di esempio Leanback ritirata .

Visualizzazione schede dell'app

Figura 1. La visualizzazione schede immagine dell'app di esempio Leanback quando è selezionata.

Crea un presentatore di schede

Un Presenter genera visualizzazioni e associa gli oggetti a queste su richiesta. Nel frammento di navigazione in cui l'app presenta i contenuti all'utente, crei un Presenter per le schede dei contenuti e lo passi all'adattatore che aggiunge i contenuti alla schermata. Nel codice seguente, CardPresenter viene creato nel callback onLoadFinished() di 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();
}

Crea una visualizzazione schede

In questo passaggio, crei il presentatore di schede con un holder di visualizzazione per la visualizzazione schede che descrive gli elementi dei contenuti multimediali. Tieni presente che ogni presentatore deve creare un solo tipo di visualizzazione. Se hai due tipi di visualizzazione schede, ti servono due presentatori di schede.

In Presenter, implementa un callback onCreateViewHolder() che crea un holder di visualizzazione che può essere utilizzato per visualizzare un elemento di contenuti:

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

Nel metodo onCreateViewHolder(), crea una visualizzazione schede per gli elementi di contenuti. L'esempio seguente utilizza un ImageCardView.

Quando una scheda viene selezionata, il comportamento predefinito la espande a una dimensione maggiore. Se vuoi assegnare un colore diverso alla scheda selezionata, chiama setSelected() come mostrato di seguito:

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

Quando l'utente apre l'app, Presenter.ViewHolder mostra gli oggetti CardView per gli elementi di contenuti. Devi impostarli in modo che ricevano lo stato attivo dal controller D-pad chiamando setFocusable(true) e setFocusableInTouchMode(true), come mostrato nel codice seguente:

Kotlin

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

Java

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

Quando l'utente seleziona ImageCardView, questa si espande per mostrare l'area di testo con il colore di sfondo specificato, come mostrato nella Figura 1.