Fornire una visualizzazione a schede

Migliora la creazione con Compose
Crea splendide UI con un minimo codice utilizzando Jetpack Compose per il sistema operativo Android TV.

Nella lezione precedente hai creato un browser catalogo, implementato in un frammento di navigazione, che mostra un elenco di elementi multimediali. In questa lezione, creerai le visualizzazioni schede per gli elementi multimediali e e presentarle nel frammento Sfoglia.

BaseCardView e le sottoclassi mostrano i metadati associati a un elemento multimediale. La ImageCardView usata in questa lezione mostra un'immagine per i contenuti e il titolo dell'elemento multimediale.

Vedi anche l'implementazione di esempio nel Esempio di app Leanback di Google.

Visualizzazione scheda dell'app

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

Crea un presentatore della scheda

Un Presenter genera viste e associa gli oggetti on demand. Nel frammento Sfoglia in cui la tua app presenta i suoi contenuti all'utente, crei una Presenter per le schede dei contenuti e passalo all'adattatore che aggiunge i contenuti allo schermo. Nel codice seguente viene creato il campo CardPresenter nel onLoadFinished() callback 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();
}

Creare una visualizzazione schede

In questo passaggio, creerai il presentatore schede con un contenitore per la visualizzazione schede che descriva i tuoi contenuti multimediali. Tieni presente che ogni presentatore deve creare un solo tipo di visualizzazione. Se ne hai due tipi di visualizzazioni schede, devi avere due presentatori per le schede.

In Presenter, implementa un'istruzione onCreateViewHolder() che crea un contenitore vista utilizzabile 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(), creare una visualizzazione schede per i contenuti. Il seguente esempio utilizza un ImageCardView.

Quando è selezionata una scheda, il comportamento predefinito la espande a una dimensione maggiore. Se vuoi designare un colore diverso per la carta selezionata, chiama setSelected() come mostrato qui:

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 la tua app, Presenter.ViewHolder mostra gli oggetti CardView per i tuoi contenuti. Impostali per ricevere Imposta lo stato attivo sul controller D-pad chiamando setFocusable(true) e setFocusableInTouchMode(true), come mostrato nel seguente codice:

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, la colonna si espande per rivelarne l'area di testo con il colore di sfondo specificato, come mostrato nella figura 1.