Можно использовать расширяемые элементы списка с новым RecyclerView? Как ExpandableListView?
Расширяемый список с RecyclerView?
Ответ 1
Это просто сделать с менеджерами LayoutManager, все зависит от того, как вы управляете своим адаптером.
Если вы хотите развернуть раздел, вы просто добавляете новые элементы в свой адаптер после заголовка. Не забудьте вызвать notifyItemRangeInserted, когда вы это сделаете. Чтобы свернуть раздел, вы просто удаляете соответствующие элементы и вызываете notifyItemRangeRemoved(). Для любых изменений данных, которые будут соответствующим образом уведомлены, просмотр recycler будет анимировать представления. При добавлении элементов создается область, заполняемая новыми элементами, при этом исчезают новые элементы. Удаление - это противоположное. Все, что вам нужно сделать, помимо материала адаптера, - это стиль ваших представлений, чтобы передать логическую структуру пользователю.
Обновление: Райан Брукс написал статью о том, как это сделать.
Ответ 2
Получить пример реализации кода из здесь
Установить ValueAnimator внутри onClick of 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();
}
}
Ответ 3
https://github.com/gabrielemariotti/cardslib
В этой библиотеке есть реализация расширяемого списка с recyclerview (см. демонстрационное приложение под "CardViewNative" → "Список, сетка и RecyclerView" → "Расширяемые карты" ). В нем также есть много других интересных комбинаций карт/списков.
Ответ 4
Кто-то жаловался, что вышеупомянутое решение не может использоваться в качестве расширяемого контента. Но есть простое решение: создать список и заполнить этот список вручную своими строками.
Решение для ленивых: есть простое решение, если вы не хотите сильно менять свой код. Просто используйте адаптер для создания представлений и добавьте их в 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
Ответ 5
Вы можете использовать ExpandableLayout, как плавное расширение/сбой анимации CheckBox, поэтому вы можете использовать его как CheckBox в ListView и RecyclerView.
Ответ 6
Это пример кода для того, что указано @TonicArtos, чтобы добавлять и удалять элементы и анимировать их во время выполнения, это берется из Анимации RecyclerView и Пример 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 не находится в том же действии, что и просмотр ресайклеров, передайте экземпляр recyclerView в Adapter при создании p >
5) itemList - это массив ArrayList типа mObject, который помогает поддерживать состояние элемента (Open/Close), имя, тип элемента (subItems/mainItem) и задавать Тема, основанная на значениях
public class mObject{
private String label;
private int type;
private boolean checked;
}