Match_parent does not work as expected

I believe this should be fairly easy to answer if you understand XML layouts better than me. It doesn't seem to me what I thought when I use match_parent layout_height.

I have a root element LinearLayout with android: orientation = "vertical" . Inside this LinearLayout I want three elements: - TextView - View list - TextView

For both TextViews, I set android: layout_height = "wrap_content" so that they are only the height needed to display their contents. The thing is, I want one TextView to sit at the top of the form and another to the bottom of the form, while the ListView fills all the space available on the form. So here is what my xml layout looks like:

<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="30sp" android:text="Top TextView" /> <ListView android:id="@+id/listView_Species" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="30sp" android:text="Bottom TextView" /> 

But that will not work. Here is what I get. I selected ListView so that it is highlighted. Notice how it extends to the very end of the form, pushing the bottom TextView out of the form. XML Layout 1

When I change the layout_height ListView property to some fixed value, like 180dp, it looks like this. I just post this to prove that there is a bottom TextView, but I still don't know how to make it snap to the bottom of the screen, while the ListView takes up all the space, but between the two TextViews.

XML Layout 2

Thanks in advance.

+6
source share
3 answers

While other answers try to fix your problem (which they don’t actually offer - they suggest you do something similar, but may or may not look good on different devices), no one has filled in the gaps in your knowledge of LinearLayouts and match_parent . And these gaps are very common - Google documentation is still far below stellar.

First, how does Views work in LinearLayout? Let's look at the LinearLayout drawing process using orientation="vertical" for simplicity.

  • Examine the height of the first LinearLayout child (LL brief description). If the height is match_parent or fill_parent (the old name for the same thing), then the height of the view is stretched to fill the entire viewport. If the height is wrap_content , then measure the vertical space that the view occupies, and use that space for the view. If height is a nonzero number, use exactly the same number of pixels for the height of the view (perhaps a clip if it is too small). If the height is 0, see below.
  • Place the next view under the view in 1. Check its height and act accordingly.
  • Continue viewing all submissions. If the view is shifted down, continue and stop calculating, because no one will see it or any subsequent views (except for ScrollView).
  • If the height of the view is 0, check its gravity . This requires a second pass, maintaining gravity of all kinds, and then proportionally distributing their heights. As you can guess, the second pass doubles the temporary layout, which is not essential for simple layouts.

Explanation of your example : the first child LL (the first TextView) is measured and takes up a certain number of pixels. Then your ListView takes up all the remaining space (via match_parent ). And then your second TextView is not drawn at all, as it is at the bottom of the screen. This is pretty much what you observed, but now you understand why.

Solution . Use RelativeLayout . In this case, it works fine.

 <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/top_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:textSize="30sp" android:text="Top TextView" /> <TextView android:id="@+id/bottom_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:textSize="30sp" android:text="Bottom TextView" /> <ListView android:id="@+id/listView_Species" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/top_tv" android:layout_above="@id/bottom_tv" /> </RelativeLayout> 

RelativeLayout tells the layout builder to draw the first TextView at the top, then draw the second TextView at the bottom, and then fill the rest of the space with the ListView. I believe that this is exactly what you want.

Welcome to Android. You will use this LOT template!

+7
source

Change ListView height to 0dp and add weight=1
those.:

 <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="30sp" android:text="Top TextView" /> <ListView android:id="@+id/listView_Species" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="30sp" android:text="Bottom TextView" /> 
+11
source

use android: layout_weight to define the weights for your widgets inside the outermost layout. Declare their height as 0dp , and then define android:layout_weight for each of them. The total weight of the three of them should be 1. According to your need, you can define a weight of 0.1 for the upper and lower text and define 0.8 in the ListView.

 <TextView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight = "0.1" android:textSize="30sp" android:text="Top TextView" /> <ListView android:id="@+id/listView_Species" android:layout_width="match_parent" android:layout_weight = "0.8" android:layout_height="0dp" /> <TextView android:layout_width="match_parent" android:layout_height="0dp" android:textSize="30sp" android:layout_weight = "0.1" android:text="Bottom TextView" /> 
+3
source

Source: https://habr.com/ru/post/951966/


All Articles