Просто немає необхідності використовувати сторонні бібліотеки. Трохи підправити в методі показано в 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 (пізніше для гнучкості)