Просто немає необхідності використовувати сторонні бібліотеки. Трохи підправити в методі показано в Google I / O 2016 і Гейзенберга по цій темі, робить трюк.
Оскільки notifyDataSetChanged() перемальовує повнеRecyclerView , notifyDataItemChanged()є кращим варіантом (не найкращим), оскільки у нас є позиція та ViewHolderнаше розпорядження, і notifyDataItemChanged()лише перемальовуємо конкретного ViewHolderв даній позиції .
Але проблема полягає в тому, що передчасне зникнення ViewHolderпісля натискання і його виникнення не усувається, навіть якщо notifyDataItemChanged()воно використовується.
Наступний код НЕ вдаватися до notifyDataSetChanged()або notifyDataItemChanged()і випробувано на API 23 і працює як шарм при використанні на RecyclerView , де кожен ViewHolder має , CardViewяк це кореневий елемент:
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являє собою глобальне ціле число, ініційоване на -1.
details- це повний вигляд, який відображається при розгортанні та маскуванні при згортанні.
Як вже говорилося, кореневих елементом ViewHolderє CardViewз foregroundі stateListAnimatorатрибути визначаються точно так же , як сказав Гейзенберг по цій темі.
ОНОВЛЕННЯ: Наведена вище демонстрація згортає попередньо розширений елемент, якщо один із них розгорнуто. Щоб змінити цю поведінку та зберегти розгорнутий елемент таким, яким він є, навіть коли інший елемент розгорнуто, вам знадобиться наступний код.
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);
ОНОВЛЕННЯ: Під час розширення останніх елементів у списку він може не бути повністю видимим, оскільки розгорнута частина йде нижче екрана. Щоб отримати повний елемент на екрані, використовуйте наступний код.
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);
ВАЖЛИВО: Щоб вищезгадані демонстрації спрацювали, потрібно зберегти у своєму коді примірник RecyclerView & це LayoutManager (пізніше для гнучкості)