Simplesmente não há necessidade de usar bibliotecas de terceiros. Um pequeno ajuste no método demonstrado no Google I / O 2016 e Heisenberg neste tópico, faz o truque.
Uma vez que notifyDataSetChanged() redesenha o completoRecyclerView , notifyDataItemChanged()é uma opção melhor (não a melhor) porque temos a posição e a ViewHolderdisposição e notifyDataItemChanged()apenas redesenha o particular ViewHolderem uma determinada posição .
Mas o problema é que o desaparecimento prematuro do ViewHolderclique e seu surgimento não são eliminados, mesmo quenotifyDataItemChanged() sejam utilizados.
O código a seguir não recorrer a notifyDataSetChanged()ou notifyDataItemChanged()e é testado em API 23 e funciona como um encanto quando usado em uma RecyclerView onde cada ViewHolder tem um CardViewcomo do elemento raiz:
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final boolean visibility = holder.details.getVisibility()==View.VISIBLE;
if (!visibility)
{
holder.itemView.setActivated(true);
holder.details.setVisibility(View.VISIBLE);
if (prev_expanded!=-1 && prev_expanded!=position)
{
recycler.findViewHolderForLayoutPosition(prev_expanded).itemView.setActivated(false);
recycler.findViewHolderForLayoutPosition(prev_expanded).itemView.findViewById(R.id.cpl_details).setVisibility(View.GONE);
}
prev_expanded = position;
}
else
{
holder.itemView.setActivated(false);
holder.details.setVisibility(View.GONE);
}
TransitionManager.beginDelayedTransition(recycler);
}
});
prev_positioné um número inteiro global inicializado com -1.
detailsé a visualização completa que é mostrada quando expandida e oculta quando recolhida.
Como dito, o elemento raiz de ViewHolderé um CardViewcom foregrounde stateListAnimatoratributos definidos exatamente como dito por Heisenberg neste tópico.
ATUALIZAÇÃO: A demonstração acima reduzirá o item previamente expandido se um deles estiver expandido. Para modificar esse comportamento e manter o item expandido como ele é, mesmo quando outro item for expandido, você precisará do código a seguir.
if (row.details.getVisibility()!=View.VISIBLE)
{
row.details.setVisibility(View.VISIBLE);
row.root.setActivated(true);
row.details.animate().alpha(1).setStartDelay(500);
}
else
{
row.root.setActivated(false);
row.details.setVisibility(View.GONE);
row.details.setAlpha(0);
}
TransitionManager.beginDelayedTransition(recycler);
ATUALIZAÇÃO: ao expandir os últimos itens da lista, ele pode não ser totalmente visível porque a parte expandida fica abaixo da tela. Para obter o item completo na tela, use o seguinte código.
LinearLayoutManager manager = (LinearLayoutManager) recycler.getLayoutManager();
int distance;
View first = recycler.getChildAt(0);
int height = first.getHeight();
int current = recycler.getChildAdapterPosition(first);
int p = Math.abs(position - current);
if (p > 5) distance = (p - (p - 5)) * height;
else distance = p * height;
manager.scrollToPositionWithOffset(position, distance);
IMPORTANTE: Para que as demonstrações acima funcionem, é necessário manter em seu código uma instância do RecyclerView e do LayoutManager (o posterior para flexibilidade)