Tidak perlu menggunakan perpustakaan pihak ketiga. Sebuah tweak dalam metode ditunjukkan dalam Google I / O 2016 dan Heisenberg tentang topik ini, melakukan trik.
Karena notifyDataSetChanged() menggambar ulang yang lengkapRecyclerView , notifyDataItemChanged()adalah pilihan yang lebih baik (bukan yang terbaik) karena kita memiliki posisi dan kemampuan yang ViewHolderkita miliki, dan notifyDataItemChanged()hanya menggambar ulang yang khusus ViewHolderpada posisi tertentu .
Tetapi masalahnya adalah bahwa hilangnya prematur ViewHolderpada mengklik dan kemunculannya tidak dihilangkan bahkan jika notifyDataItemChanged()digunakan.
Kode berikut ini tidak menggunakan notifyDataSetChanged()atau notifyDataItemChanged()dan Diuji pada API 23 dan berfungsi seperti pesona ketika digunakan pada RecyclerView di mana setiap ViewHolder memiliki CardViewelemen root seperti itu:
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_positionadalah integer global yang diinisialisasi ke -1.
detailsadalah tampilan lengkap yang ditampilkan saat diperluas dan terselubung saat diciutkan.
Seperti yang dikatakan, elemen root dari ViewHolderadalah CardViewdengan foregrounddan stateListAnimatoratribut didefinisikan persis seperti yang dikatakan oleh Heisenberg pada topik ini.
UPDATE: Demonstrasi di atas akan runtuh item yang sudah diperluas sebelumnya jika salah satu dari mereka di diperluas. Untuk memodifikasi perilaku ini dan menjaga item yang diperluas seperti ketika item lain diperluas, Anda akan memerlukan kode berikut.
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);
UPDATE: Ketika memperluas item terakhir dalam daftar, itu mungkin tidak dibawa ke visibilitas penuh karena bagian yang diperluas berada di bawah layar. Untuk mendapatkan item lengkap di layar gunakan kode berikut.
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);
PENTING: Agar demonstrasi di atas berfungsi, seseorang harus menyimpan dalam kode mereka instance dari RecyclerView & itu LayoutManager (nanti untuk fleksibilitas)