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 ViewHolder
kita miliki, dan notifyDataItemChanged()
hanya menggambar ulang yang khusus ViewHolder
pada posisi tertentu .
Tetapi masalahnya adalah bahwa hilangnya prematur ViewHolder
pada 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 CardView
elemen 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_position
adalah integer global yang diinisialisasi ke -1.
details
adalah tampilan lengkap yang ditampilkan saat diperluas dan terselubung saat diciutkan.
Seperti yang dikatakan, elemen root dari ViewHolder
adalah CardView
dengan foreground
dan stateListAnimator
atribut 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)