I have the following screen basket_fragment.xml:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.RecyclerView android:id="@+id/basket_fragment_recycler_view" android:layout_width="match_parent" android:layout_height="wrap_content"> </android.support.v7.widget.RecyclerView> </LinearLayout> 

RecyclerView contains CardView which in its. the queue is set in this way basket_card_view.xml:

 <android.support.v7.widget.CardView android:id="@+id/basket_fragment_card_view" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" <!--this 200 dp!-->> android:layout_margin="8dp" android:elevation="6dp" app:cardBackgroundColor="@android:color/white" app:cardCornerRadius="8dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp"> <TextView android:id="@+id/basket_fragment_card_view_text_view_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Recipe Name" android:textSize="20sp" android:textStyle="bold"/> <ListView android:id="@+id/basket_fragment_card_view_list_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_below="@+id/basket_fragment_card_view_text_view_title" android:choiceMode="multipleChoice"> </ListView> </RelativeLayout> </android.support.v7.widget.CardView> 

The problem is that only one item from the ListView displayed.

enter image description here If you strictly define the size of CardView , for example android:layout_height="200dp" , then the list items are displayed (as high as possible).

How to get rid of this problem and make it so that the size of the card ( CardView ) depended on the internal filling ( wrap_content ) taking into account the number of elements?

UPD . Maybe I'm wrong in terms of choosing a widget to display a list of lines with checkboxes (that is, in this case, for example, it would be more rational to use dynamic addition of elements to, for example, some LinearLayout in the code itself), but I still have some problem

  • 2
    The problem is that your foliage is placed in recyclerview. get rid of it - Android Android
  • @Android I changed the display somewhat, replaced the ListView with LinearLayout (vertical), determined the new xml responsible for the display I needed (the line with the checkbox), and dynamically in the code, in the for-each loop I create (inflate) and add it to the container (the one that LinearLaout) display. But the question is - how reasonable and competent is it from the development side? I would like to do by working code, the same quality and clear - abbath0767
  • It seems that you are inventing a crutch. Why are you trying to fill your layout with a cycle? After all, for such a purpose, you have RecyclerView, which seems to be standing idle for now =) You only need to write an adapter for it and drive the list with your objects. - Android Android
  • Replace ListView with RecyclerView, it will stretch your CardView correctly. @AndroidAndroid we are talking about a nested list in each item RecyclerView - Yura Ivanov
  • @AndroidAndroid is possible. But maybe I did not correctly described the structure of the screen. The fragment contains Recycler, it in turn contains a certain set of CardView, it in turn contains more elements and one of them is just a static (for each CardView its own) list, which I defined as LinearLayout. In the fragment, I redefined the Adapter and ViewHolder which works for the cards, and just in one of the ViewHolder methods I fill the list in the cards with the data. Do you suggest replacing this list (in my case LinearLayout) with another RecyclerView with your adapter and viewholder? - abbath0767

1 answer 1

I solved the problem as follows - I replaced the ListView nested in each CardView with LinearLayout , a kind of container that should contain the necessary mappings for each element that I add dynamically in the code during the rendering of each CardView element from RecyclerView . This is how the onBindRecipeViewHolder method in ViewHolder now looks for my RecyclerView , which is called in the Adapter in the onBindViewHolder method

 public void onBindRecipeViewHolder(Recipe recipe) { recipeTitle.setText(recipe.getTitle()); elementList = RecipeElementLab.get(getActivity()).getRecipeElements(recipe.getId().toString()); Log.d(MainActivity.TAG, "elements = " + elementList); for (RecipeElement elem: elementList) { LinearLayout anotherElementLL = (LinearLayout) LayoutInflater.from(getActivity()) .inflate(R.layout.basket_card_view_element_item, null); anotherElementLL.setId(View.generateViewId()); container.addView(anotherElementLL); TextView elemName = (TextView) anotherElementLL.findViewById(R.id.basket_fragment_card_view_layout_text_view_ingr_name); elemName.setText(elem.getName() + " / " + elem.getCount()); } } 

And now everything looks correct

enter image description here

I would be grateful if you can advise a more correct way to achieve this result, because it gnaws the feeling that this method is not the most correct

  • It is a working solution, but I recommend you take out the container inflite and findViewById() from the loop. These are very resource-intensive operations, and you perform them for each element in the cycle, although their result does not change during the execution of the cycle. - pavlofff
  • @pavlofff I may have misunderstood you, but the container itself inflates with me once, and in the cycle the "small" LinearLayout containing the string and checkbox inflates and added to the container. Or do you mean that the object that I called anotherElementLL, in the loop, assign only an id each time and then add it with a new id? - abbath0767
  • Yes of course. inflate anotherElementLL and get the reference to elemName to take out of the loop - create these objects before filling starts and use the same object for all elements in the loop. These are too “expensive” operations to be wasted every time. In addition, if you do not use the ID for anotherElementLL (this is not visible in the code), then there is no need to assign it, the container ID is needed only if you want to access it (and not the widgets that are attached to it) from the code. - pavlofff
  • The problem will be when it will be necessary to catch clicks on jackdaws and update the data. Everything will jump when upgrading. - Yura Ivanov