
MergeAdapter é uma nova classe introduzida em recyclerview: 1.2.0-alpha02 que permite combinar vários adaptadores de vídeo em um único RecyclerView. Isso permitirá que você encapsule a lógica para cada célula em seu adaptador e permitirá que você a reutilize no futuro.
Problema
Vamos começar com um exemplo. Suponha que temos a tarefa de exibir um feed com dois tipos de dados - um texto com uma descrição e uma imagem. O código no método
onCreateViewHolder
no caso mais comum será parecido com este:
override fun onCreateViewHolder(
parent: ViewGroup, viewType: Int
): RecyclerView.ViewHolder? {
val holder: RecyclerView.ViewHolder
val inflater = LayoutInflater.from(parent.context)
when (viewType) {
TEXT_VIEW_TYPE -> {
holder = TextViewHolder(
inflater.inflate(R.layout.text_item, parent, false)
)
}
IMAGE_VIEW_TYPE -> {
holder = ImageViewHolder(
inflater.inflate(R.layout.image_item, parent, false),
imageClickListener
)
}
else -> {
throw IllegalArgumentException(
"Can't create view holder from view type $viewType"
)
}
}
return holder
}
Por que isso é ruim? A desvantagem desta implementação é a violação dos princípios de SECO e SÓLIDO (responsabilidade única e aberto fechado). Para ter certeza disso, basta adicionar dois requisitos: inserir um novo tipo de dado (checkbox) e mais uma fita, onde haverá apenas checkboxes e imagens.
Estamos diante de uma escolha - usar o mesmo adaptador para a segunda fita ou criar um novo? Independentemente da solução que escolhermos, teremos que alterar o código (quase a mesma coisa, mas em lugares diferentes). Será necessário adicionar um novo VIEW_TYPE, ViewHolder novos e editar métodos:
getItemViewType(), onCreateViewHolder() onBindViewHolder()
.
Se decidirmos manter um adaptador, as alterações terminarão aí. Mas se no futuro novos tipos de dados com nova lógica forem adicionados apenas ao segundo feed, o primeiro terá funcionalidade extra e também precisará ser testado, embora não tenha mudado.
Se decidirmos criar um novo adaptador, haverá muitos códigos duplicados.
Decisão
A nova classe MergeAdapter permite combinar diferentes adaptadores para diferentes tipos de células. Por exemplo, um caso de uso muito comum é exibir um botão giratório ao carregar dados no feed e, se, de repente, ocorrer um erro de carregamento, exibir uma célula com um erro no final do feed.

A solução para este problema pode ser o uso de MergeAdapter. Suponha que temos 3 adaptadores:
val firstAdapter: FirstAdapter = …
val secondAdapter: SecondAdapter = …
val thirdAdapter: ThirdAdapter = …val mergeAdapter = MergeAdapter(firstAdapter, secondAdapter, thirdAdapter)
recyclerView.adapter = mergeAdapter
O RecyclerView exibirá os itens de cada adaptador sequencialmente, na mesma ordem em que foram passados para o construtor. Adaptadores diferentes permitem separar a lógica para células diferentes na lista. Por exemplo, se você precisa adicionar um título à lista, você não precisa implementar esta lógica no adaptador, que é responsável por exibir o conteúdo principal da lista, você pode separar os adaptadores para diferentes tipos de células. Essa abordagem ajuda a encapsular a lógica e reutilizá-la no futuro para diferentes telas.

Exiba o download no cabeçalho ou no final da lista.
Para exibir o status do download na parte superior ou inferior da lista, adicione adaptadores, respectivamente:
val mergeAdapter = MergeAdapter(headerAdapter, listAdapter, footerAdapter)
recyclerView.adapter = mergeAdapter
A célula superior e a inferior usam o mesmo layout, ViewHolder e lógica da IU (mostrar o status de carregamento e ocultar). Em geral, seria suficiente usar 2 instâncias do mesmo adaptador para o início e o fim da lista. Um exemplo pode ser encontrado aqui ou aqui .
Resumindo, de forma simples você pode melhorar o código do seu projeto se usar um adaptador complexo com diferentes tipos de células.
Você gostou do artigo? Não se esqueça de se juntar a nós no Telegram e na plataforma AndroidSchool.ru , materiais úteis para desenvolvedores Android e tutoriais modernos são publicados.