Можна використовувати елементи списку, що розширюються, за допомогою нового RecyclerView? Подобається ExpandableListView?
Можна використовувати елементи списку, що розширюються, за допомогою нового RecyclerView? Подобається ExpandableListView?
Відповіді:
Це просто зробити із стандартним LayoutManagers, все залежить від того, як ви керуєте своїм адаптером.
Коли ви хочете розгорнути розділ, ви просто додаєте нові елементи до свого адаптера після заголовка. Не забудьте зателефонувати до notifyItemRangeInserted, коли ви це робите. Щоб згорнути розділ, ви просто видаляєте відповідні елементи та викликаєте notifyItemRangeRemoved (). Для будь-яких змін даних, про які повідомлено належним чином, подання утилізатора анімує подання. При додаванні предметів робиться область, яку потрібно заповнити новими предметами, при цьому нові предмети зникають. Видалення відбувається навпаки. Все, що вам потрібно зробити, крім матеріалів адаптера, - це створити стилі своїх поглядів, щоб передати логічну структуру користувачеві.
Оновлення: Райан Брукс написав статтю про те, як це зробити.
Отримайте зразок реалізації коду звідси
Встановіть ValueAnimator усередині onClick 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();
}
Ось остаточний код
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
", оскільки розширений вміст у цьому випадку є самим списком з елементами, що надходять із адаптера. Це вироджене рішення, в якому для дітей всередині групи дозволено лише 1 предмет.
https://github.com/gabrielemariotti/cardslib
Ця бібліотека має реалізацію розширюваного списку з переглядом recicler (див. Демонстраційний додаток у розділі "CardViewNative" -> "Список, сітка та RecyclerView" -> "Розширювані картки"). Він також має безліч інших цікавих комбінацій карт / списків.
Хтось скаржився на те, що вищезазначене рішення не можна використовувати з переглядом списку як розширеним вмістом. Але є просте рішення: створити перегляд списку та заповнити цей перегляд вручну своїми рядками .
Рішення для ледачих: є просте рішення, якщо ви не хочете сильно змінювати свій код. Просто використовуйте адаптер вручну для створення подань та додавання їх до LinearLayout
.
Ось приклад:
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);
}
допоміжні функції: 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;
}
}
допоміжний клас: ExpandUtils
Кавін Варнан вже повідомив, як анімувати макет ... Але якщо ви хочете скористатися моїм класом, сміливо робіть це, я розмістив суть: https://gist.github.com/MichaelFlisar/738dfa03a1579cc7338a
recyclerview
і ви можете розгорнути / приховати цей вкладений і використовувати всі оптимізаціїrecyclerview
Ви можете використовувати ExpandableLayout, який подобається плавній анімації розгортання / згортання CheckBox, тому ви можете використовувати його як CheckBox у ListView та RecyclerView.
Це зразок коду для того, що згадується @TonicArtos для додавання та видалення елементів та анімації його під час, це взято з RecyclerView Animations та зразка GitHub
1) Додайте слухача до свого onCreateViewHolder (), щоб зареєструватися для onClick
2) Створіть власний OnClickListener всередині адаптера
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 () та deleteItem ()
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 перебуває не в тій самій діяльності, що і Recycler View , передайте екземпляр recyclerView в адаптер під час створення
5) itemList - це ArrayList типу mObject, який допомагає підтримувати стан елемента (Відкрити / Закрити), ім'я, тип Елемента (subItems / mainItem) та встановлювати Тему на основі значень
public class mObject{
private String label;
private int type;
private boolean checked;
}