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:

 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.

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 🙂

  • ¿Por qué no hay espacio entre CardViews en Lollipop?
  • Error al inflar la clase y android.support.v7.widget.CardView
  • Cómo deshabilitar la sombra alrededor de la vista de la tarjeta en android
  • Comportamiento de sombra extraño durante el cambio de tarjeta
  • Android pone Cardview en la parte superior de Cardview padre en RelativeLayout
  • CardView inserta la línea oscura en la parte inferior
  • Cómo configurar el relleno para el widget CardView en Android L
  • CardView ignorando el androide: clipChildren = "false"
  • "No se pudo encontrar el estilo con id 0x7f070001 en el tema actual" cuando se utiliza CardView android L (api 21)
  • Desplazamiento horizontal y vertical en la vista del reciclador android
  • Diferente ancho de diseño dentro de RecyclerView y LinearLayout normal
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.