Mungkinkah menggunakan item daftar yang dapat diperluas dengan RecyclerView baru? Suka ExpandableListView?
Mungkinkah menggunakan item daftar yang dapat diperluas dengan RecyclerView baru? Suka ExpandableListView?
Jawaban:
Ini mudah dilakukan dengan LayoutManagers stok, semuanya tergantung pada bagaimana Anda mengelola adaptor Anda.
Saat Anda ingin memperluas bagian, Anda cukup menambahkan item baru ke adaptor Anda setelah header. Ingatlah untuk memanggil notifyItemRangeInserted saat Anda melakukan ini. Untuk menciutkan bagian Anda cukup menghapus item yang relevan, dan memanggil notifyItemRangeRemoved (). Untuk setiap perubahan data yang diberitahukan dengan tepat, tampilan daur ulang akan menganimasikan tampilan. Saat menambahkan item, area yang akan diisi dengan item baru dibuat, dengan item baru memudar. Penghapusan adalah sebaliknya. Yang perlu Anda lakukan selain hal-hal adaptor adalah mengatur gaya tampilan Anda untuk menyampaikan struktur logis kepada pengguna.
Pembaruan: Ryan Brooks sekarang telah menulis artikel tentang cara melakukan ini.
Dapatkan implementasi kode sampel dari sini
Setel ValueAnimator di dalam onClick dari ViewHolder
@Override
public void onClick(final View view) {
if (mOriginalHeight == 0) {
mOriginalHeight = view.getHeight();
}
ValueAnimator valueAnimator;
if (!mIsViewExpanded) {
mIsViewExpanded = true;
valueAnimator = ValueAnimator.ofInt(mOriginalHeight, mOriginalHeight + (int) (mOriginalHeight * 1.5));
} else {
mIsViewExpanded = false;
valueAnimator = ValueAnimator.ofInt(mOriginalHeight + (int) (mOriginalHeight * 1.5), mOriginalHeight);
}
valueAnimator.setDuration(300);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
view.getLayoutParams().height = value.intValue();
view.requestLayout();
}
});
valueAnimator.start();
}
Ini kode terakhirnya
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView mFriendName;
private int mOriginalHeight = 0;
private boolean mIsViewExpanded = false;
public ViewHolder(RelativeLayout v) {
super(v);
mFriendName = (TextView) v.findViewById(R.id.friendName);
v.setOnClickListener(this);
}
@Override
public void onClick(final View view) {
if (mOriginalHeight == 0) {
mOriginalHeight = view.getHeight();
}
ValueAnimator valueAnimator;
if (!mIsViewExpanded) {
mIsViewExpanded = true;
valueAnimator = ValueAnimator.ofInt(mOriginalHeight, mOriginalHeight + (int) (mOriginalHeight * 1.5));
} else {
mIsViewExpanded = false;
valueAnimator = ValueAnimator.ofInt(mOriginalHeight + (int) (mOriginalHeight * 1.5), mOriginalHeight);
}
valueAnimator.setDuration(300);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
view.getLayoutParams().height = value.intValue();
view.requestLayout();
}
});
valueAnimator.start();
}
}
ExpandableListView", karena konten yang diperluas dalam kasus tersebut adalah daftar itu sendiri dengan item yang berasal dari adaptor. Ini adalah solusi yang merosot dengan hanya 1 item yang diperbolehkan sebagai anak-anak di dalam grup.
https://github.com/gabrielemariotti/cardslib
Library ini memiliki implementasi daftar yang dapat diperluas dengan recyclerview (lihat aplikasi demo di bawah "CardViewNative" -> "List, Grid, and RecyclerView" -> "Kartu yang dapat diperluas"). Ini juga memiliki banyak kombinasi kartu / daftar keren lainnya.
Seseorang mengeluh tentang solusi yang disebutkan di atas tidak dapat digunakan dengan listview sebagai konten yang dapat diperluas. Tetapi ada solusi sederhana: buat listview dan isi listview ini secara manual dengan baris Anda .
Solusi untuk yang malas: ada solusi sederhana jika Anda tidak ingin terlalu banyak mengubah kode. Cukup gunakan adaptor Anda secara manual untuk membuat tampilan dan menambahkannya ke LinearLayout.
Berikut contohnya:
if (mIsExpanded)
{
// llExpandable... is the expandable nested LinearLayout
llExpandable.removeAllViews();
final ArrayAdapter<?> adapter = ... // create your adapter as if you would use it for a ListView
for (int i = 0; i < adapter.getCount(); i++)
{
View item = adapter.getView(i, null, null);
// if you want the item to be selectable as if it would be in a default ListView, then you can add following code as well:
item.setBackgroundResource(Functions.getThemeReference(context, android.R.attr.selectableItemBackground));
item.setTag(i);
item.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// item would be retrieved with:
// adapter.getItem((Integer)v.getTag())
}
});
llExpandable.addView(item);
}
ExpandUtils.expand(llExpandable, null, 500);
}
else
{
ExpandUtils.collapse(llExpandable, null, 500);
}
fungsi pembantu: getThemeReference
public static int getThemeReference(Context context, int attribute)
{
TypedValue typeValue = new TypedValue();
context.getTheme().resolveAttribute(attribute, typeValue, false);
if (typeValue.type == TypedValue.TYPE_REFERENCE)
{
int ref = typeValue.data;
return ref;
}
else
{
return -1;
}
}
kelas helper: ExpandUtils
Kavin Varnan sudah memposting cara menganimasikan tata letak ... Tetapi jika Anda ingin menggunakan kelas saya, silakan melakukannya, saya memposting intinya: https://gist.github.com/MichaelFlisar/738dfa03a1579cc7338a
recyclerviewdan Anda dapat memperluas / menyembunyikan satu bersarang ini dan menggunakan semua optimisations darirecyclerview
Anda dapat menggunakan ExpandableLayout yang menyukai kotak centang animasi luaskan / ciutkan yang mulus, sehingga Anda dapat menggunakannya sebagai Kotak Centang di ListView dan RecyclerView.
Ini adalah kode contoh untuk apa yang disebutkan oleh @TonicArtos untuk menambah dan menghapus Item dan untuk menganimasikannya saat melakukannya, ini diambil dari contoh RecyclerView Animations dan GitHub
1) Tambahkan Listener di dalam onCreateViewHolder () Anda untuk mendaftar onClick
2) Buat OnClickListener kustom Anda di dalam Adapter Anda
private View.OnClickListener mItemListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView tv = (TextView) v.findViewById(R.id.tvItems);
String selected = tv.getText().toString();
boolean checked = itemsList.get(recyclerView.getChildAdapterPosition(v)).isChecked();
switch (selected){
case "Item1":
if(checked){
deleteItem(v);
itemsList.get(recyclerView.getChildAdapterPosition(v)).setChecked(false);
}else {
addItem(v);
itemsList.get(recyclerView.getChildAdapterPosition(v)).setChecked(true);
}
break;
case "Item2":
if(checked){
deleteItem(v);
itemsList.get(recyclerView.getChildAdapterPosition(v)).setChecked(false);
}else {
addItem(v);
itemsList.get(recyclerView.getChildAdapterPosition(v)).setChecked(true);
}
break;
default:
//In my case I have checkList in subItems,
//checkItem(v);
break;
}
}
};
3) Tambahkan addItem () dan deleteItem () Anda
private void addItem(View view){
int position = recyclerView.getChildLayoutPosition(view);
if (position != RecyclerView.NO_POSITION){
navDrawItems.add(position+1,new mObject());
navDrawItems.add(position+2,new mObject());
notifyItemRangeInserted(position+1,2);
}
}
private void deleteItem(View view) {
int position = recyclerView.getChildLayoutPosition(view);
if (position != RecyclerView.NO_POSITION) {
navDrawItems.remove(position+2);
navDrawItems.remove(position+1);
notifyItemRangeRemoved(position+1,2);
}
}
4) Jika RecyclerViewAdapter Anda tidak dalam Aktivitas yang sama dengan Recycler View , teruskan instance recyclerView ke Adapter saat membuat
5) itemList adalah ArrayList berjenis mObject yang membantu mempertahankan status item (Buka / Tutup), nama, jenis Item (subItems / mainItem) dan mengatur Tema berdasarkan nilai
public class mObject{
private String label;
private int type;
private boolean checked;
}