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 ViewHolder
disposição e notifyDataItemChanged()
apenas redesenha o particular ViewHolder
em uma determinada posição .
Mas o problema é que o desaparecimento prematuro do ViewHolder
clique 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 CardView
como 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 CardView
com foreground
e stateListAnimator
atributos 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)