Cómo agregar un recicladorVer dentro de otro recicladorVer
Estoy planeando desarrollar una aplicación que muestra algunos datos dinámicos dentro de un recyclerCardView
. Así que decidí añadir un recyclerView
llamado CheckBoxRecyclerView
dentro de mi recyclerView
principal. Este es mi código para mi aplicación:
Mi actividad principal:
- Uso de CardView en Android 5.0 en Eclipse
- Uso de android.support.v7.widget.CardView en mi proyecto (Eclipse)
- ¿Cómo funciona el concepto RecyclerView en android?
- Cambiar el color de fondo de CardView mediante programación
- Espacio en blanco con CardView en dispositivos pre-pirulí
setContentView(R.layout.activity_startup); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); reminderView = (RecyclerView) findViewById(R.id.reminder_recycler_view); RlayoutManager = new LinearLayoutManager(this); reminderView.setLayoutManager(RlayoutManager); setSupportActionBar(toolbar); cardView = (CardView) findViewById(R.id.card_first); cardView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getApplicationContext() , ReminderActivity.class); startActivity(intent); } }); ReminderHelper helper = new ReminderHelper(getApplicationContext()); ReminderAdapter reminderAdapter = new ReminderAdapter(helper); ContentValues reminderValues = new ContentValues(); ContentValues checkboxValues = new ContentValues(); // Devlopment Part -> reminderValues.put("reminderTitle" , "A Reminder Title"); reminderValues.put("reminderLastModDate" , 0); reminderValues.put("reminderAlarm" , 0); reminderValues.put("reminderPicURI" , "skjshksjh"); reminderValues.put("ReminderBackground" , "#00796b"); checkboxValues.put("checkboxText" , "This is a CheckBox"); checkboxValues.put("isDone" , false); checkboxValues.put("checkboxReminderID" , 0); reminderAdapter.INSERT_REMINDER(reminderValues); reminderAdapter.INSERT_CHECKBOX(checkboxValues); File dbPath = getApplicationContext().getDatabasePath(ReminderHelper.DATABASE_NAME); if(dbPath.exists()){ List<Reminder> reminders = new ReminderAdapter(helper).getAllReminders(); List<CheckBoxItem> checkBoxItems = new ReminderAdapter(helper).getAllCheckBoxes(); RAdapter = new RAdapter(reminders , getApplicationContext() , checkBoxItems); reminderView.setAdapter(RAdapter); }else{ }
Y es el archivo de diseño:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="8dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="8dp" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="com.smflog.sreminder.StartupActivity" tools:showIn="@layout/app_bar_startup"> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:id="@+id/reminder_recycler_view" android:scrollbars="vertical" android:layout_height="match_parent">
Y dentro de este recyclerView hay otro:
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/reminder_card" card_view:cardCornerRadius="2dp" card_view:cardElevation="4dp" card_view:cardUseCompatPadding="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="16dp" android:paddingLeft="8dp"> <com.smflog.sreminder.utils.TitleView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/reminder_title" android:paddingTop="8dp" android:text="Wellcome To Google Keep !" android:textSize="15dp" android:textStyle="bold" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <android.support.v7.widget.RecyclerView android:layout_width="wrap_content" android:id="@+id/checkbox_recycler_view" android:layout_height="wrap_content"> </android.support.v7.widget.RecyclerView> </LinearLayout> </LinearLayout> </android.support.v7.widget.CardView>
Sus adaptadores, Main (RAdapter):
public class RAdapter extends RecyclerView.Adapter<RAdapter.ViewHolder> { List<Reminder> reminder; private Context context; private LinearLayoutManager lln; private CAdapter checkBoxAdapter; private List<CheckBoxItem> checkBoxItems; public static class ViewHolder extends RecyclerView.ViewHolder { public CardView rCardView; public RecyclerView recyclerView; public TitleView rTitleView; public ViewHolder(View itemView) { super(itemView); rCardView = (CardView) itemView.findViewById(R.id.reminder_card); rTitleView = (TitleView) itemView.findViewById(R.id.reminder_title); recyclerView = (RecyclerView) itemView.findViewById(R.id.checkbox_recycler_view); } } public RAdapter(List<Reminder> reminder, Context context, List<CheckBoxItem> checkBoxItems) { this.reminder = reminder; this.context = context; this.checkBoxItems = checkBoxItems; } @Override public RAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.reminder_card, parent, false); ViewHolder vh = new ViewHolder(v); return vh; } @Override public void onBindViewHolder(RAdapter.ViewHolder holder, int position) { lln = new LinearLayoutManager(context); holder.recyclerView.setLayoutManager(lln); checkBoxAdapter = new CAdapter(checkBoxItems, context); holder.recyclerView.setAdapter(checkBoxAdapter); holder.rCardView.setCardBackgroundColor(Color.parseColor("#00796b")); holder.rTitleView.setText(reminder.get(position).getReminderTitle()); } @Override public int getItemCount() { return reminder.size(); } }
Y segundo Adaptador:
public class CAdapter extends RecyclerView.Adapter<CAdapter.ViewHolder> { List<CheckBoxItem> checkBoxItems; Context context; public static class ViewHolder extends RecyclerView.ViewHolder { public TitleView checkBoxTitle; public ImageView deleteCheckBox; public CheckBox checkBoxCheckBox; public ViewHolder(View itemView) { super(itemView); checkBoxTitle = (TitleView) itemView.findViewById(R.id.checkbox_item_text); checkBoxCheckBox = (CheckBox) itemView.findViewById(R.id.checkbox_item_checkbox); Log.d("CAdapterLog", "Adpater Holded !!!!! :( "); deleteCheckBox = (ImageView) itemView.findViewById(R.id.btn_delete_checkbox); } } public CAdapter(List<CheckBoxItem> checkBoxItems, Context context) { this.checkBoxItems = checkBoxItems; this.context = context; Log.d("CAdapterLog", "Adpater Created !!!!! :( "); } @Override public CAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.checkbox_item, parent, false); ViewHolder vh = new ViewHolder(v); Log.d("CAdapterLog", "Adpater ViewHolded :( !!!!! :( "); return vh; } @Override public void onBindViewHolder(CAdapter.ViewHolder holder, int position) { Boolean isCheckboxChecked = Boolean.parseBoolean(checkBoxItems.get(position).getCheckBoxIsDone()); String checkBoxText = checkBoxItems.get(position).getCheckBoxBody(); Log.d("CAdapterLog", "Adpater Binded :( "); final int checkboxID = Integer.parseInt(checkBoxItems.get(position).getCheckBoxID()); int reminderCheckBoxID = Integer.parseInt(checkBoxItems.get(position).getCheckBoxReminderID()); holder.deleteCheckBox.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("CAdapterLog", "Cross Button Clicked !"); } }); holder.checkBoxCheckBox.setChecked(isCheckboxChecked); holder.checkBoxTitle.setText(checkBoxText); } @Override public int getItemCount() { return checkBoxItems.size(); } }
Y mi problema: como se ve en CAdapter, sólo se muestra el mensaje de registro del constructor.
UPDATE : si hay otra forma de mostrar algunos datos dinámicos dentro de otra tarjeta dinámica, si es mejor usarla en lugar de recyclerView?
Alguien me ayude
La salida: La salida de la aplicación como se ve sólo el setTitle para RAdapter funciona.
- Expandiendo / Colapsando CardView con un gesto de clic o de deslizamiento (Android)?
- Expanda / contrae la animación en CardView
- Cardview - Establece diferentes colores de fondo para cada elemento
- Retroalimentación de RecyclerView + CardView + Touch
- El evento de clic de los padres no se activa cuando se hace clic en recyclerview
- Android NestedScrollView alinear el contenido en la parte superior
- ¿Por qué utilizar un CardView en lugar de un RelativeLayout o LinearLayout?
- Cardview inmovilizado gris subrayado (dispositivos Android 4.0.4)
No es muy habitual agregar un RecyclerView
dentro de otro. Me gustaría sugerir el uso de un único RecyclerView
y rellenar dinámicamente los elementos de la lista. He añadido un proyecto github para describir cómo se puede hacer esto. Usted puede echar un vistazo. Mientras que las otras soluciones funcionarán bien, me gustaría sugerir, esta es una forma mucho más rápida y eficiente de mostrar múltiples listas en un RecyclerView
.
La idea es agregar lógica en su método onCreateViewHolder
y onBindViewHolder
para que pueda inflar la vista adecuada para las posiciones exactas en su RecyclerView
.
He añadido un proyecto de ejemplo junto con ese wiki también. Puede clonar y comprobar lo que hace.
Hay otra forma de mantener los elementos en un único ArrayList
de objetos para que pueda establecer un atributo etiquetando los elementos para indicar qué elemento es de la primera lista y cuál pertenece a la segunda lista. A continuación, pasar que ArrayList
en su RecyclerView
y, a continuación, implementar la lógica dentro del adaptador para rellenar dinámicamente.
Espero que ayude.
Me encontré con un problema similar hace un tiempo atrás y lo que estaba sucediendo en mi caso era la vista de reciclar exterior estaba funcionando perfectamente bien, pero el adaptador de la vista interior / segundo reciclador había problemas menores todos los métodos como constructor se inició e incluso método getCount Estaba siendo llamado, aunque los métodos finales responsables de generar vista es decir ..
1. Los métodos onBindViewHolder () nunca se llamaron. -> Problema 1.
2. Cuando se llamó finalmente nunca mostrar la lista de elementos / filas de la vista de reciclador. -> Problema 2.
Razón por la que sucedió esto : Cuando coloca una vista de reciclador dentro de otra vista de reciclador, la altura de la vista de primer / reciclador externo no se ajusta automáticamente. Se define cuando se crea la vista primera / externa y luego permanece fija. En ese momento su segundo / recolector interno vista todavía no ha cargado sus elementos y por lo tanto su altura se establece como cero y nunca cambia, incluso cuando se obtiene datos. Luego, cuando se llama onBindViewHolder () en su segunda vista de recolector interna, obtiene elementos pero no tiene el espacio para mostrarlos porque su altura sigue siendo cero. Por lo tanto, los elementos de la segunda vista de reciclador nunca se muestran aunque el onBindViewHolder () los haya añadido.
Solución :: usted tiene que crear su LinearLayoutManager personalizado para la segunda vista de reciclador y que es. Para crear su propio LinearLayoutManager: Cree una clase Java con el nombre CustomLinearLayoutManager
y pegue el código a continuación en él. NO SE REQUIEREN CAMBIOS
public class CustomLinearLayoutManager extends LinearLayoutManager { private static final String TAG = CustomLinearLayoutManager.class.getSimpleName(); public CustomLinearLayoutManager(Context context) { super(context); } public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { super(context, orientation, reverseLayout); } private int[] mMeasuredDimension = new int[2]; @Override public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { final int widthMode = View.MeasureSpec.getMode(widthSpec); final int heightMode = View.MeasureSpec.getMode(heightSpec); final int widthSize = View.MeasureSpec.getSize(widthSpec); final int heightSize = View.MeasureSpec.getSize(heightSpec); int width = 0; int height = 0; for (int i = 0; i < getItemCount(); i++) { measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), mMeasuredDimension); if (getOrientation() == HORIZONTAL) { width = width + mMeasuredDimension[0]; if (i == 0) { height = mMeasuredDimension[1]; } } else { height = height + mMeasuredDimension[1]; if (i == 0) { width = mMeasuredDimension[0]; } } } switch (widthMode) { case View.MeasureSpec.EXACTLY: width = widthSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } switch (heightMode) { case View.MeasureSpec.EXACTLY: height = heightSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } setMeasuredDimension(width, height); } private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { try { View view = recycler.getViewForPosition(position); if (view != null) { RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), p.width); int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, getPaddingTop() + getPaddingBottom(), p.height); view.measure(childWidthSpec, childHeightSpec); measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin; measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin; recycler.recycleView(view); } } catch (Exception e) { e.printStackTrace(); } }
}
Puede utilizar LayoutInflater para inflar sus datos dinámicos como un archivo de diseño.
ACTUALIZACIÓN : primero cree un LinearLayout dentro del diseño de CardView y asigne un ID para él. Después de crear un archivo de diseño que desea inflar. Por fin en su método onBindViewHolder
en su clase "RAdaper". Escribe estos códigos:
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = mInflater.inflate(R.layout.my_list_custom_row, parent, false);
Después de que usted puede inicializar datos y ClickListeners con sus datos de RAdapter. Espero eso ayude.
Esto y esto puede ser útil 🙂
- Android – Carousel como widget que muestra una parte de los elementos izquierdo y derecho
- ¿Cómo quitar el texto emergente de la búsqueda del android de búsqueda mientras que busca?