Yeni RecyclerView ile genişletilebilir liste öğelerini kullanmak mümkün mü? ExpandableListView gibi mi?
Yeni RecyclerView ile genişletilebilir liste öğelerini kullanmak mümkün mü? ExpandableListView gibi mi?
Yanıtlar:
Bu, stok LayoutManager'larla yapmak kolaydır, hepsi adaptörünüzü nasıl yönettiğinize bağlıdır.
Bir bölümü genişletmek istediğinizde, başlıktan sonra adaptörünüze yeni öğeler eklemeniz yeterlidir. Bunu yaptığınızda notifyItemRangeInserted'ı çağırmayı unutmayın. Bir bölümü daraltmak için ilgili öğeleri kaldırmanız ve notifyItemRangeRemoved () öğesini çağırmanız yeterlidir. Uygun şekilde bildirilen herhangi bir veri değişikliği için geri dönüşümcü görünümü görünümleri canlandıracaktır. Öğe eklerken, yeni öğelerle doldurulacak bir alan yapılır ve yeni öğeler kaybolur. Kaldırma tam tersidir. Bağdaştırıcı şeyler dışında yapmanız gereken tek şey, mantıksal yapıyı kullanıcıya iletmek için görünümlerinizi şekillendirmektir.
Güncelleme: Ryan Brooks şimdi bunun nasıl yapılacağına dair bir makale yazdı .
Örnek kod uygulamasını buradan alın
OnClick of ViewHolder içinde ValueAnimator'ı ayarlayın
@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();
}
İşte son kod
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" çalışmaz , çünkü bu durumda genişletilmiş içerik adaptörden gelen öğelerin bulunduğu bir listedir. Bu, grup içinde çocukken yalnızca 1 maddeye izin verilen dejenere bir çözümdür.
https://github.com/gabrielemariotti/cardslib
Bu kitaplık, geri dönüşüm görünümüne sahip genişletilebilir bir liste uygulamasına sahiptir ("CardViewNative" -> "List, Grid ve RecyclerView" -> "Genişletilebilir kartlar" altındaki demo uygulamasına bakın). Aynı zamanda birçok başka harika kart / liste kombinasyonuna sahiptir.
Birisi, yukarıda bahsedilen çözümün genişletilebilir içerik olarak bir liste görünümüyle kullanılamayacağından şikayet etti. Ancak basit bir çözüm var: bir liste görünümü oluşturun ve bu liste görünümünü manuel olarak satırlarınızla doldurun .
Tembel olanlar için çözüm : Kodunuzu fazla değiştirmek istemiyorsanız basit bir çözüm var. Görünümler oluşturmak için adaptörünüzü manuel olarak kullanın ve bunları LinearLayout.
İşte örnek:
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);
}
yardımcı işlevler: 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;
}
}
yardımcı sınıf: ExpandUtils
Kavin Varnan postet zaten bir mizanpajı nasıl canlandırabilirim ... Ama eğer sınıfımı kullanmak istiyorsanız, bunu yapmaktan çekinmeyin, bir özet yayınladım: https://gist.github.com/MichaelFlisar/738dfa03a1579cc7338a
recyclerviewve iç içe geçmiş olanı genişletebilir / gizleyebilir verecyclerview
Düzgün bir genişletme / daraltma animasyonu CheckBox gibi ExpandableLayout'u kullanabilirsiniz, böylece ListView ve RecyclerView'da CheckBox olarak kullanabilirsiniz.
Bu, @TonicArtos tarafından Öğeleri eklemek ve kaldırmak ve bunu yaparken hareketlendirmek için bahsedilenler için örnek koddur , bu RecyclerView Animations ve GitHub örneğinden alınmıştır.
1) onClick'e kaydolmak için onCreateViewHolder () içerisine Dinleyici ekleyin
2) Bağdaştırıcınızın içinde özel OnClickListener oluşturun
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) addItem () ve deleteItem () öğenizi ekleyin
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) RecyclerViewAdapter'ınız Recycler View ile aynı Activity'de değilse, oluştururken recyclerView örneğini Bağdaştırıcıya geçirin
5) itemList, öğenin durumlarını (Aç / Kapat), adı, Öğe türünü (subItems / mainItem) korumaya ve değerlere dayalı Tema ayarlamaya yardımcı olan mObject türünde bir ArrayListtir
public class mObject{
private String label;
private int type;
private boolean checked;
}