What is android:weightSum in android, and how does it work?

前端 未结 9 882
梦毁少年i
梦毁少年i 2020-11-22 04:02

I want to know: What is android:weightSum and layout weight, and how do they work?

9条回答
  •  一整个雨季
    2020-11-22 04:15

    After some experimenting, I think the algorithm for LinearLayout is this:

    Assume that weightSum is set to a value. The case of absence is discussed later.

    First, divide the weightSum by the number of elements whith match_parent or fill_parent in the dimension of the LinearLayout (e.g. layout_width for orientation="horizontal"). We will call this value the weight multiplier w_m for each element. The default value for weightSum is 1.0, so the default weight multiplier is 1/n, where n is the number of fill_parent elements; wrap_content elements do not contribute to n.

    w_m = weightSum / #fill_parent

    E.g. when weightSum is 60, and there are 3 fill_parent elements, the weight multiplier is 20. The weight multiplier is the default value for e.g. layout_width if the attribute is absent.

    Second, the maximum possible expansion of every element is computed. First, the wrap_content elements are computed according to their contents. Their expansion is deducted from the expansion of the parent container. We will call the remainer expansion_remainer. This remainder is distributed among fill_parent elements according to their layout_weight.

    Third, the expansion of every fill_parent element is computed as:

    w_m - ( layout_weight / w_m ) * maximum_possible_expansion

    Example:

    If weightSum is 60, and there are 3 fill_parent elements with the weigths 10, 20 and 30, their expansion on the screen is 2/3, 1/3 and 0/3 of the parent container.

    weight | expansion
         0 | 3/3
        10 | 2/3
        20 | 1/3
        30 | 0/3
        40 | 0/3
    

    The minimum expansion is capped at 0. The maximum expansion is capped at parent size, i.e. weights are capped at 0.

    If an element is set to wrap_content, its expansion is calculated first, and the remaining expansion is subject to distribution among the fill_parent elements. If weightSum is set, this leads to layout_weight having no effect on wrap_content elements. However, wrap_content elements can still be pushed out of the visible area by elements whose weight is lower than weight multiplier (e.g. between 0-1 for weightSum= 1 or between 0-20 for the above example).

    If no weightSum is specified, it is computed as the sum of all layout_weight values, including elements with wrap_content set! So having layout_weight set on wrap_content elements, can influence their expansion. E.g. a negative weight will shrink the other fill_parent elements. Before the fill_parent elements are laid out, will the above formula be applied to wrap_content elements, with maximum possible expansion being their expansion according to the wrapped content. The wrap_content elements will be shrunk, and afterwards the maximum possible expansion for the remaining fill_parent elements is computed and distributed.

    This can lead to unintuitive results.

提交回复
热议问题