studio recyclerview cardview android android-recyclerview

android - cardview - ¿Lista expandible con RecyclerView?



android studio recyclerview expandable (7)

¿Es posible usar elementos de lista expandibles con el nuevo RecyclerView? ¿Te gusta ExpandableListView?


Alguien se quejó de que la solución mencionada anteriormente no se puede usar con una vista de lista como contenido expandible. Pero hay una solución simple: cree una vista de lista y complete esta vista de lista manualmente con sus filas .

Solución para los perezosos: hay una solución simple si no quieres cambiar mucho tu código. Simplemente use su adaptador manualmente para crear vistas y agregarlas a LinearLayout .

Aquí está el ejemplo:

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); }

funciones de ayuda: 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; } }

clase auxiliar: ExpandUtils

Kavin Varnan ya publicó cómo animar un diseño ... Pero si desea usar mi clase, siéntase libre de hacerlo, publiqué una idea esencial: https://gist.github.com/MichaelFlisar/738dfa03a1579cc7338a


Este es el código de muestra de lo que @TonicArtos menciona para agregar y eliminar elementos y animarlo mientras lo hace, esto se toma de RecyclerView Animations y muestra de GitHub

1) Agregue Listener dentro de su onCreateViewHolder () para registrarse en onClick

2) Cree su OnClickListener personalizado dentro de su adaptador

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) Agregue su addItem () y 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) Si su RecyclerViewAdapter no está en la misma actividad que Recycler View , pase la instancia de recyclerView al adaptador mientras crea

5) itemList es una ArrayList de tipo mObject que ayuda a mantener los estados del elemento (Abrir / Cerrar), nombre, tipo de Elemento (subItems / mainItem) y establecer el Tema en función de los valores

public class mObject{ private String label; private int type; private boolean checked; }


Esto es simple de hacer con los LayoutManagers de stock, todo depende de cómo administre su adaptador.

Cuando desee expandir una sección, simplemente agregue nuevos elementos a su adaptador después del encabezado. Recuerde llamar a notifyItemRangeInserted cuando haga esto. Para contraer una sección, simplemente elimine los elementos relevantes y llame a notifyItemRangeRemoved (). Para cualquier cambio de datos que se notifique adecuadamente, la vista del reciclador animará las vistas. Al agregar elementos, se crea un área para rellenar con los nuevos elementos, con los nuevos elementos desapareciendo. La eliminación es lo contrario. Todo lo que necesita hacer además del adaptador es diseñar sus vistas para transmitir la estructura lógica al usuario.

Actualización: Ryan Brooks ahora ha escrito un article sobre cómo hacer esto.


Obtenga la implementación del código de muestra desde here

Establezca ValueAnimator en 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(); }

Aquí está el código final

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(); } }



Simplemente puede cambiar su código para obtener la máxima legibilidad. Por lo tanto, debe usar el método notifyItemChanged() lugar del valor animator. Mira .com/a/48092441/5962715 para esto. Puede ahorrar mucho tiempo al hacerlo.

simplemente use notifyItemChanged () `cuando sea necesario colapsar y expandir vistas.

No use ninguna biblioteca o código complejo para esto.

ver .com/a/48092441/5962715


https://github.com/gabrielemariotti/cardslib

Esta biblioteca tiene una implementación de una lista expandible con una vista de reciclado (consulte la aplicación de demostración en "CardViewNative" -> "Lista, cuadrícula y RecyclerView" -> "Tarjetas expandibles"). También tiene muchas otras combinaciones geniales de tarjetas / listas.