Comment ajouter un recyclerVoir à l'intérieur d'un autre recyclerVoir

Je prévois de développer une application qui montre des données dynamiques dans un recyclerCardView . J'ai donc décidé d'ajouter un recyclerView appelé CheckBoxRecyclerView intérieur de mon principal recyclerView . C'est mon code pour mon application:

Ma principale activité:

  • Téléchargement d'une image depuis Android (avec Android Asynchronous Http Client) vers un serveur de rails (avec un trombone)
  • Exécution Android RunOnUiThread
  • Android: conversion Color To Int
  • Android ActionBar Personnaliser la vue de recherche
  • Android BottomSheet: Est-ce que l'on trouve sous la barre d'outils
  • Android - Inclure les fonctionnalités natives de StageFright dans mon propre projet
  •  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{ } 

    Et c'est le fichier de mise en page:

     <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"> 

    Et à l'intérieur de ce recycler. Il y a un autre:

     <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> 

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

    Et deuxième adaptateur:

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

    Et mon problème: comme vous le voyez dans CAdapter, seul le message Log du constructeur s'affiche.

    MISE À JOUR : s'il existe une autre façon d'afficher certaines données dynamiques dans une autre carte dynamique si oui, est-il préférable de l'utiliser au lieu de recyclerView?
    Quelqu'un m'aide?
    La sortie: sortie d' application que vous voyez juste que le setTitle pour RAdapter fonctionne.

  • Endpoint d'application AppEngine Android Auth and InApp Billing
  • Trouver le "Nom de la classe Android" dans "AndroidManifest.xml" généré par Unity3D
  • Identifier et annuler une alarme envoie à un AlarmManager
  • Erreur lors de l'ajout d'un projet de bibliothèque dans eclipse
  • IDE "Impossible de résoudre @ style / Theme.Appcompat" lors de l'utilisation du thème de compatibilité v7
  • Le fichier contient un séparateur de chemin.
  • 3 Solutions collect form web for “Comment ajouter un recyclerVoir à l'intérieur d'un autre recyclerVoir”

    Il n'est pas rare d'ajouter un RecyclerView intérieur d'un autre. J'aimerais suggérer d'utiliser un seul RecyclerView et de remplir vos éléments de liste dynamiquement. J'ai ajouté un projet github pour décrire comment cela peut être fait. Vous pourriez avoir un coup d'œil. Bien que les autres solutions fonctionnent très bien, j'aimerais suggérer qu'il s'agisse d'une manière beaucoup plus rapide et efficace d'afficher plusieurs listes dans RecyclerView .

    L'idée est d'ajouter une logique dans votre méthode onCreateViewHolder et onBindViewHolder afin que vous puissiez gonfler la vue appropriée pour les positions exactes dans votre RecyclerView .

    J'ai ajouté un exemple de projet avec ce wiki aussi. Vous pouvez cloner et vérifier ce qu'il fait.

    Il existe une autre façon de conserver vos objets dans une seule ArrayList d'objets afin que vous puissiez définir un attribut de marquage des éléments pour indiquer quel élément est de la première liste et lequel appartient à la deuxième liste. Ensuite, passez cette ArrayList dans votre RecyclerView , puis implémentez la logique interne de l'adaptateur pour les remplir dynamiquement.

    J'espère que cela pourra aider.

    J'ai rencontré un problème similaire depuis un certain temps et ce qui se passait dans mon cas était que la vue externe du recycleur fonctionnait parfaitement bien, mais l'adaptateur de la vue interne / deuxième recycleur avait des problèmes mineurs, toutes les méthodes comme constructeur ont été initiées et même la méthode getCount () Était appelé, bien que les méthodes finales responsables de générer une vue, c'est-à-dire …

    1. Les méthodes onBindViewHolder () n'ont jamais été appelées. -> Problème 1.

    2. Lorsqu'il a été appelé finalement, il ne montre jamais la liste des éléments / lignes de la vue du recycleur. -> Problème 2.

    Raison pour laquelle cela s'est produit :: Lorsque vous placez une vue de recyclage dans une autre vue de recycleur, la hauteur de la première vue de recycleur externe n'est pas réglée automatiquement. Il est défini lorsque la première vue / externe est créée, puis elle reste fixe. À ce stade, votre deuxième vue de recycleur interne n'a pas encore chargé ses objets et donc sa hauteur est définie comme nulle et ne change jamais même lorsqu'il obtient des données. Ensuite, lorsque onappelleBindViewHolder () dans votre deuxième vue de recycleur interne, il obtient des éléments, mais il n'a pas l'espace pour les afficher car sa hauteur est toujours nulle. Ainsi, les éléments de la deuxième vue de recyclage ne sont jamais affichés même lorsque onBindViewHolder () les a ajoutés.

    Solution : vous devez créer votre LinearLayoutManager personnalisé pour la deuxième vue du recycleur et c'est tout. Pour créer votre propre LinearLayoutManager: créez une classe Java avec le nom CustomLinearLayoutManager et collez le code ci-dessous. NON CHANGEMENTS REQUIS

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

    }

    Vous pouvez utiliser LayoutInflater pour gonfler vos données dynamiques en tant que fichier de mise en page.

    MISE À JOUR : créez d'abord un LinearLayout dans la mise en page de votre CardView et attribuez-lui une ID. Ensuite, créez un fichier de mise en page que vous souhaitez gonfler. Enfin dans votre méthode onBindViewHolder dans votre classe "RAdaper". Écrivez ces codes:

      mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = mInflater.inflate(R.layout.my_list_custom_row, parent, false); 

    Après cela, vous pouvez initialiser les données et ClickListeners avec vos données RAdapter. J'espère que cela aide.

    Ceci et cela peut être utile 🙂

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.