layout_weight does not work when the layout inside

2020-06-29 07:32发布

问题:

I'm trying to use a linear layout's layout_weight for the height inside of a scrollview. However I find that layout_weight would only work with fillViewPort=true and if there is enough remaining space for the linear_weight to expand.

I have listed three examples below and I want to make textView the same size in #2 and #3 as #1 in xml level. As you can see in the link, in #2, #3, textView was automatically changed.

Here are my examples. The TextViews and Buttons are enclosed inside of a LinearLayout and then inside of a scrollView.

1. Layout_weight working perfectly relative to the parent. (Working)

2. Layout_weight working relative to the remaining space and not the parent.(Not Working)

3 Layout_weight ignored (Not Working)

Here's my xml code for #3. #2 and #1 is basically the same code with less or no buttons.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/scroller"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:weighSum="1"
    android:fillViewport="true" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:weightSum="10" >

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />

        <Button
            android:layout_width="30dip"
            android:layout_height="30dip"
            android:text="Accept" />


        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="6"
            android:background="#AAABBB"
            android:text="hello" />

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="3"
            android:background="#BBBAAA"

            android:text="hello" />

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="5"
            android:background="#AAABBB"

            android:text="hello" />
    </LinearLayout>

</ScrollView>

回答1:

The weights are working as they were designed. Maybe not the way you want them to "work", but saying they are "not working" is inaccurate. Think about your 3rd case for a second, what size in pixels would you expect the TextViews to be? Weights are a percentage of the available space (not total size of the parent). The scrollview and linearlayout are, at a minimum, the size of your screen, otherwise the sum of all the children views. So if your children views exceed the size of the screen (the ones without weights), how much space do you expect to be allocated for the remaining views (the ones with 0dp and weights)? The point is that amount of space is arbitrary, android will not try to assume how much space you want, because it has no possible way of knowing.

TL;DR - set a minHeight (in dp) on your textviews to handle the case where you have too many buttons.



回答2:

The images are exactly what I would expect to see for your xml.

This may help you:

  1. When the system is layout putting the Views on the screen using the weight approach, it allocates only the spare space according to the weight, not the total space. Therefore, to make it allocate the total space be allocated according to the weights (which is what most people intuitively expect), you have to set the dimension you want it to work in to 0dip. So, for those Buttons and TextViews you need to set

    android:layout_height = "0dip"
    
  2. You may also need to force the ScrollView to fill the viewport to stop everything scrunching up. See here

    android:fillViewport="true"
    
  3. A personal observation. Sometimes weights seem to work in inverse (ie smaller weights give more space). YMMV.



回答3:

Try setting layout_height="0dp" on the elements that have layout_weight. The enclosing layout object will use any free space to grow them as much as it can.

Also your use of weightSum is a bit questionable. Normally weightSum should be >= the total weights of the enclosed views. You have one weightSum where none of the directly enclosed views have weight and another where the total weight of the enclosed views exceeds weightSum. This second case will lead to strange behavior.