Layout_weight in Android

Source: Internet
Author: User

SDK description

Indicates how much ofExtra spaceIn the linearlayout will be allocated to the view associated with these layoutparams. Specify 0 if the view shoshould not be stretched. Otherwise the extra pixels will bePro-ratedAmong all views whose weight is greater than 0.

There are two important points. One is layout_weight, which indicates the division of additional space in linearlayout (the size before layout_weight may be extended), and the other is proportional.

The following uses Android: Orientation = "horizontal" as an example.

After reading the source code, although not quite familiar with it, I understood the general meaning and summarized it according to my own understanding. I directly wrote the simplifiedCode(The following code is a simplified part of the linearlayout source file. The variable name may have an inaccurate meaning. This is a convenient description ):

 //  Either expand children with weight to take up available space or
// Shrink them if they extend beyond our current Bounds
Int Delta = widthsize-mtotallength;
If (Delta! = 0 & totalweight> 0.0f ){
Float Weightsum = mweightsum> 0.0f? Mweightsum: totalweight;
For ( Int I = 0; I <count; ++ I ){
Final View child = getvirtualchildat (I );

If (Child =Null | Child. getvisibility () = view. Gone ){
Continue ;
}

Final Linearlayout. layoutparams Lp =
(Linearlayout. layoutparams) child. getlayoutparams ();

Float Childextra = LP. weight;
If (Childextra> 0 ){
Int Share = ( Int ) (Childextra * Delta/weightsum );
Weightsum-= childextra;
Delta-= share;
 
IntChildwidth = Child. getmeasuredwidth () + share;
If(Childwidth <0 ){
Childwidth = 0;
}
}
}
}

Variable meaning

Widthsize: the width of linearlayout.

Mtotallength: Sum of the width of all sub-views (layout_weight is not considered)

Totalweight: Sum of layout_weight of all child views

Android: weightsum attribute of mweihtsum: linearlayout

Process Analysis:

First, the extra space (which can be negative) is calculated. If the extra space is not 0 and the layout_weight of a sub-view is not 0, the extra space will be allocated based on layout_weight:

 
IntDelta = widthsize-mtotallength;
If(Delta! = 0 & totalweight> 0.0f ){
...
}

If weightsum is set for linearlayout, the sum of layout_weight of the sub-view is overwritten:

FloatWeightsum = mweightsum> 0.0f? Mweightsum: totalweight;

Then traverse the child element of linearlayout. If it is not null and visibility is not gone, obtain its layoutparams. If its layout_weight is greater than 0, calculate the extra space allocated to weightsum based on its weight.

 
If(Childextra> 0 ){
IntShare = (Int) (Childextra * Delta/weightsum );
Weightsum-= childextra;
Delta-= share;

IntChildwidth = Child. getmeasuredwidth () + share;
If(Childwidth <0 ){
Childwidth = 0;
}
}

It is explained on the Internet that layout_weight indicates the importance and the priority of additional space. It is wrong to know this idea through code. layout_weight indicates the proportion of the partition. If layout_width of the view is fill_parent, the opposite proportion of layout_weight can be explained as follows:

For example, the following XML:

 <? XML version = "1.0" encoding = "UTF-8"  ?> 
< Linearlayout Xmlns: Android = "Http://schemas.android.com/apk/res/android"
Android: layout_width = "Fill_parent"
Android: layout_height = "Wrap_content"
Android: Background = "#00ff00"
Android: weightsum = "0"
Android: Orientation = "Horizontal" >

< Button
Android: ID = "@ + ID/imageviewloginstate"
Android: layout_width = "Fill_parent"
Android: layout_height = "Fill_parent"
Android: layout_weight = "1"
Android: Text = "1" >
</ Button >

< Button
Android: ID = "@ + ID/imageviewloginstate1"
Android: layout_width = "Fill_parent"
Android: layout_height = "Fill_parent"
Android: layout_weight = "1"
Android: Text = "2" >
</ Button >

< Button
Android: ID = "@ + ID/imageviewloginstate2"
Android: layout_width = "Fill_parent"
Android: layout_height = "Fill_parent"
Android: layout_weight = "2"
Android: Text = "3" >
</ Button >

</ Linearlayout >

Generally, the ratio of the three buttons should be, but the actual situation is as follows:

In my understanding, the system sets the button size in this way, and the variable name follows the meaning of the previous Code:

Assume that the container (linearlayout) width is parent_width.

The width of the three buttons is fill_parent. Therefore, before layout_width is applied, the width of the three buttons is parent_width.

So the extra space Delta = parent_width-3 * parent_width =-2 * parent

Because Android: weightsum is not set for linearlayout (the default value is 0 and it is set to 0), mweightsum = 1 + 1 + 2 = 4

Therefore:

The width of the first button is parent_width + share = parent_width + (layout_weight * Delta/mweightsum) = parent_width + (1*(-2 * parent_width)/4) = 1/2 * parent_width

 
Weightsum-= childextra; (= 3)
Delta-= share; (=-3/2 * parent_width)

The width of the second button is parent_width + share = parent_width + (layout_weight * Delta/mweightsum) = parent_width + (1*(-3/2 * parent_width)/3) = 1/2 * parent_width

 
Weightsum-= childextra; (= 2)
Delta-= share; (=-parent_width)

The width of the third button is parent_width + share = parent_width + (layout_weight * Delta/mweightsum) = parent_width + (2 * (-parent_width)/2) = 0

So in the end, the first two buttons are evenly divided into linearlayout, and the third button disappears.

 

The general process is as follows, but not all. For example, if the weightsum of linearlayout in the preceding example is set to 2, the width of the first two buttons is 0, however, when the width of the third button is calculated as mweightsum = 0, layout_weight * Delta/mweightsum cannot be calculated, and the system does not know how to handle it. It is out of my ability, when weightsum is 2:

When weightsum is 3:

 

In the SDK, layout_weight indicates how to divide the extra space. Pay attention to the additional two words. You need additional space to allocate it to the subview with layout_weight configured in proportion, therefore, if linearlayout is set to wrap_content, there is no extra space, and layout_weight is useless. As long as layout_width is not set to wrap_content, it can also be set to a specific value, if the value is too small, the extra space is negative, and the Child control may be compressed to make it smaller than the size defined in the XML file. For example:

 <?  XML version = "1.0" encoding = "UTF-8"  ?> 
< Linearlayout Xmlns: Android = "Http://schemas.android.com/apk/res/android"
Android: layout_width = "100dp"
Android: layout_height = "Wrap_content"
Android: Background = "#00ff00"
Android: Orientation = "Horizontal" >

< Button
Android: ID = "@ + ID/button1"
Android: layout_width = "60dp"
Android: layout_height = "Fill_parent"
Android: layout_weight = "1"
Android: Text = "1" >
</ Button >

< Button
Android: ID = "@ + ID/button2"
Android: layout_width = "60dp"
Android: layout_height = "Fill_parent"
Android: layout_weight = "1"
Android: Text = "2" >
</ Button >

< Button
Android: ID = "@ + ID/button3"
Android: layout_width = "60dp"
Android: layout_height = "Fill_parent"
Android: layout_weight = "2"
Android: Text = "3" >
</ Button >

</ Linearlayout >

Extra space Delta = 100-3*60 =-80

Mweightsum = 1 + 1 + 2 = 4

Therefore:

The width of the first button is 60 + share = 60 + (layout_weight * Delta/mweightsum) = 60 + (1 * (-80)/4) = 40

 
Weightsum-= childextra; (= 3)
Delta-= share; (=-60)

The width of the second button is 60 + share = 60 + (layout_weight * Delta/mweightsum) = 60 + (1 * (-60)/3) = 40

Weightsum-= childextra; (= 2)
Delta-= share; (=-40)

The width of the third button is 60 + share = 60 + (layout_weight * Delta/mweightsum) = 60 + (2 * (-40)/2) = 20

:

 

The following code also shows that layout_weight indicates the allocation of extra space:

 <?  XML version = "1.0" encoding = "UTF-8"  ?> 
< Linearlayout Xmlns: Android = "Http://schemas.android.com/apk/res/android"
Android: layout_width = "200dp"
Android: layout_height = "Wrap_content"
Android: Background = "#00ff00"
Android: Orientation = "Horizontal" >

< Button
Android: ID = "@ + ID/button1"
Android: layout_width = "60dp"
Android: layout_height = "Fill_parent"
Android: layout_weight = "1"
Android: Text = "1" >
</ Button >

< Button
Android: ID = "@ + ID/button2"
Android: layout_width = "40dp"
Android: layout_height = "Fill_parent"
Android: layout_weight = "1"
Android: Text = "2" >
</ Button >


</ Linearlayout >

The extra space is 100, so the width of button1 is 60 + 100/2 = 110, and the width of button2 is 40 + 100/2 = 90

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.