O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Oferecer uma visualização de card

Na lição anterior, você criou um navegador de catálogo, implementado em um fragmento de navegação, que exibe uma lista de itens de mídia. Nesta lição, você criará as visualizações de card para seus itens de mídia e os apresentará no fragmento de navegação.

A classe BaseCardView e as subclasses apresentam os metadados associados a um item de mídia. A classe ImageCardView usada nesta lição exibe uma imagem para o conteúdo junto ao título do item de mídia.

Esta lição descreve o código do app de amostra de Leanback do Android no repositório da Android TV do GitHub (link em inglês). Use essa amostra de código para iniciar seu próprio app.

Visualização de card de apps

Figura 1. Visualização de card do app de amostra de Leanback quando selecionado.

Criar uma apresentação de card

Um Presenter gera visualizações e vincula objetos a elas sob demanda. No fragmento de navegação em que seu app apresenta conteúdo ao usuário, crie um Presenter para os cards de conteúdo e passe-o para o adaptador que adiciona o conteúdo à tela. No código a seguir, o CardPresenter é criado no callback onLoadFinished() do 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();
    }
    

Criar uma visualização de card

Nesta etapa, você criará um apresentador de card com um fixador de visualização que descreve os itens de conteúdo de mídia. Observe que cada apresentador precisa criar apenas um tipo de visualização. Se você tiver dois tipos diferentes de visualização de card, precisará de dois apresentadores de card diferentes.

No Presenter, implemente um callback onCreateViewHolder() que crie um fixador de visualização que possa ser usado para exibir um item de conteúdo.

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

No método onCreateViewHolder(), crie uma visualização de card para itens de conteúdo. A amostra abaixo usa um ImageCardView.

Quando um card é selecionado, o comportamento padrão o expande para um tamanho maior. Caso queira designar uma cor diferente para o card selecionado, chame setSelected(), como mostrado aqui.

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 o usuário abre o app, o Presenter.ViewHolder exibe os objetos CardView dos itens de conteúdo. É necessário configurá-los para receber foco do controlador de botão direcional chamando setFocusable(true) e setFocusableInTouchMode(true).

Kotlin

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

Java

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

Quando o usuário seleciona ImageCardView, ela se expande para mostrar a área de texto com a cor de plano de fundo que você especificar, como mostrado na Figura 1.