Este guia se concentra na criação das visualizações de card para seus itens de mídia e na apresentação deles no fragmento de navegação usando o kit de ferramentas de interface do Leanback descontinuado. A implementação do navegador de catálogo em um fragmento de navegação é detalhada no Guia do fragmento de navegação.
A classe BaseCardView
e as subclasses mostram os metadados associados a um item de mídia. A classe
ImageCardView
usada nesta lição mostra uma imagem para o conteúdo junto ao título do item de mídia.
Consulte também a implementação de exemplo no app de exemplo do Leanback descontinuado.

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ê vai criar o apresentador de card com um fixador de visualização para a visualização de card que descreve seus itens de conteúdo de mídia. Observe que cada apresentador precisa criar apenas um tipo de visualização. Se você tiver dois tipos de visualização de card, precisará de dois apresentadores de card.
No Presenter
, implemente um callback onCreateViewHolder()
que crie um fixador de visualização que possa ser usado para mostrar 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. O exemplo a seguir 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)
, conforme mostrado no código a seguir:
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.