Android TV — Personalizando HeaderSupportFragment
No post anterior, vimos como podemos começar a desenvolver Android TV com o BrowseSupportFragment. BrowseSupportFragment hospeda 2 fragmentos, o HeaderSupportFragment e o RowsSupportFragment. Também vimos como podemos começar a personalizar a IU de acordo com nossas necessidades.
Nesta postagem, veremos como podemos personalizar o HeaderSupportFrament para exibir ícones nos cabeçalhos de seção e também nos itens de linha, como este.
Antes da parte aparentemente complexa, vamos ver como podemos mudar o fundo da barra lateral e também a cor do Search Orb que aparece na barra lateral.
Alterando a cor do HeaderSupportFragment
brandColor = ContextCompat.getColor(requireContext(), R.color.color_primary)
searchAffordanceColor = ContextCompat.getColor(requireContext(), R.color.color_primary)
Vamos para a parte complexa agora. Para conseguir isso, você precisará fazer as seguintes coisas.
- Melhore a estrutura de dados, ou seja, HeaderItem , para poder receber um recurso Image.
- Adicione os recursos de imagem aos dados que alimentam o HeaderSupportFragment.
- Crie apresentadores personalizados que podem inflar um layout que contém um ImageView adicional
- Deixe o HeaderSupportFragment usar seus apresentadores personalizados em vez das implementações padrão.
Crie uma classe Kotlin que estenda o HeaderItem, que agora pode receber um parâmetro inteiro extra.
class MenuItem(id: Long, name: String, val icon: Int): HeaderItem(id, name) {
}
class SectionItem(id: Long, val name: String, val icon: Int): SectionRow(id, name) {
}
No projeto de exemplo, em vez de passar instâncias de HeaderItems, use instâncias de suas classes recém-criadas.
rowsAdapter.add(SectionItem(100, getString(R.string.qtv), R.drawable.ic_section_icon))
val header = MenuItem(i.toLong(), MovieList.MOVIE_CATEGORY[i], MovieList.MOVIE_ICON[i])
rowsAdapter.add(ListRow(header, listRowAdapter))
val MOVIE_ICON = arrayOf(
R.drawable.ic_home,
R.drawable.ic_today,
R.drawable.ic_puzzles,
R.drawable.ic_topics,
R.drawable.ic_fun_facts,
);
QSectionPresenter.kt
class QSectionPresenter: Presenter() {
override fun onCreateViewHolder(parent: ViewGroup?): QSectionViewHolder {
val root: View = LayoutInflater.from(parent!!.context)
.inflate(R.layout.presenter_section_row, parent, false)
val viewHolder = QSectionViewHolder(root)
return viewHolder
}
override fun onBindViewHolder(viewHolder: ViewHolder?, item: Any?) {
val headerItem = if (item == null) null else (item as SectionItem)
val sectionItem = headerItem as SectionItem
val vh = viewHolder as QSectionViewHolder
vh.tvTitle.text = sectionItem.name
Glide.with(viewHolder.view.context).load(sectionItem?.icon).into(vh.ivIcon)
}
override fun onUnbindViewHolder(viewHolder: ViewHolder?) {
val vh = viewHolder as QSectionViewHolder
vh.tvTitle.text = null
}
}
class QSectionViewHolder(view: View) : RowHeaderPresenter.ViewHolder(view) {
val tvTitle: TextView
val ivIcon: ImageView
init {
tvTitle = view.findViewById(R.id.tvTitle)
ivIcon = view.findViewById(R.id.ivItemImage)
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/ivItemImage"
android:src="@drawable/ic_home" android:tint="@color/color_accent"
android:layout_width="@dimen/sidebar_section_image_size"
android:layout_height="@dimen/sidebar_section_image_size"/>
<TextView android:id="@+id/tvTitle"
android:layout_marginStart="@dimen/margin_sidebar_image_text"
android:textStyle="italic|bold"
android:layout_width="match_parent" android:textColor="@color/color_accent"
android:text="@string/app_name"
android:textSize="@dimen/text_size_sidebar_section"
android:layout_height="wrap_content"/>
</LinearLayout>
class QTVRowPresenter : Presenter() {
override fun onCreateViewHolder(parent: ViewGroup?): QTVRowViewHolder {
val root: View = LayoutInflater.from(parent!!.context)
.inflate(R.layout.presenter_row, parent, false)
val viewHolder = QTVRowViewHolder(root)
return viewHolder
}
override fun onBindViewHolder(viewHolder: ViewHolder?, item: Any?) {
val headerItem = if (item == null) null else (item as Row).headerItem
val menuItem = headerItem as MenuItem
val vh = viewHolder as QTVRowViewHolder
vh.tvTitle.text = headerItem?.name
Glide.with(viewHolder.view.context).load(menuItem?.icon).into(vh.ivIcon)
}
override fun onUnbindViewHolder(viewHolder: ViewHolder?) {
val vh = viewHolder as QTVRowViewHolder
vh.tvTitle.text = null
}
}
class QTVRowViewHolder(view: View) : RowHeaderPresenter.ViewHolder(view) {
val tvTitle: TextView
val ivIcon: ImageView
init {
tvTitle = view.findViewById(R.id.tvTitle)
ivIcon = view.findViewById(R.id.ivItemImage)
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent" android:gravity="center_vertical"
android:layout_height="wrap_content">
<ImageView
android:contentDescription="@string/app_name"
android:id="@+id/ivItemImage"
android:src="@drawable/ic_home"
android:layout_width="@dimen/sidebar_image_size"
android:layout_height="@dimen/sidebar_image_size"/>
<TextView android:id="@+id/tvTitle"
android:textSize="@dimen/text_size_sidebar_row"
android:layout_marginStart="@dimen/margin_sidebar_image_text"
android:layout_width="wrap_content"
android:text="@string/app_name"
android:layout_height="wrap_content"/>
</LinearLayout>
val sHeaderPresenter: PresenterSelector = ClassPresenterSelector()
.addClassPresenter(DividerRow::class.java, DividerPresenter())
.addClassPresenter(
SectionRow::class.java,
QSectionPresenter()
)
.addClassPresenter(Row::class.java, QTVRowPresenter())
setHeaderPresenterSelector(sHeaderPresenter)
Agora a barra lateral parece muito melhor do que a implementação padrão. Você pode ir em frente e fazer quantas personalizações quiser, desde que tenha seus apresentadores personalizados instalados.
É tudo por agora.





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)