The ultimate study of Layout_weight in Android

Source: Internet
Author: User

Previously in the UI layout, also often with the Layout_weight property, and sometimes encountered a puzzling layout problems, but always did not study understand. Always want to do in-depth analysis, but there is no patience. If you encounter problems, find alternative solutions, but they will not last. This is the determination to get it through!

Never understand what layout_weight mean, I write code test also came out of different situations, recently read a post feeling analysis is very good, posted out to learn .


The layout file is:
<?xml version= "1.0" encoding= "Utf-8"?>
<linearlayout xmlns:android= "Http://schemas.android.com/apk/res/android"
android:orientation= "Horizontal"
Android:layout_width= "Fill_parent"
android:layout_height= "Fill_parent"
>
<button
Android:layout_width= "Fill_parent"
android:layout_height= "Wrap_content"
android:layout_weight= "1"
android:text= "Button1"
/>
<button
Android:layout_width= "Fill_parent"
android:layout_height= "Wrap_content"
Android:layout_weight= "2"
android:text= "Button2"
/>
</LinearLayout>
The layout that appears is: Button1 accounted for the 2/3,button2 accounted for 1/3.


However, if you change the property of the button in the layout file android:layout_width= "fill_parent" to Android:layout_width= "wrap_content" The result is: Button1 accounted for 1 /3,button2 accounted for 2/3.

What does it mean to end up like this? Here is the explanation: reproduced here:

Reprint of the explanation *********
When a child with weight is included in the LinearLayout, LinearLayout will measure two times:
Set the screen width to X
First: Button1 's measuredwidth is X,button2 and X (because weight is used, so linearlayout does not take into account the size of the previous one each time measure child), Total_width is 2X
Second: Calculates the delta=x-total_width=-x and then sets the width of the button1 to
x+delta*1/3=0.66x, the width of the button2 is x+delta*2/3=0.33x
Then I'm going to recap this sentence: "Because the weight of the button1 is the smallest, so it occupies a higher priority of the layout," perhaps in the Android layout and there is no priority to say, I here just to illustrate the problem, I define, so friends do not shoot bricks.
Well, first of all, when the layout_width is set to Fill_parent, it fills the father's office, which means that the control is going to be as large as the weight, so, in the case of the above example, the weight of Button1 is 1, The weight of the button2 is set to 2. That is, the button is the highest priority, so to fill the parent will be button1 first to fill, as large as possible, then this may be how much, this will ci the other controls in the layout weight value, and then do the calculation, Button1 occupies the 1/3 of 2/3,button2. You can also set the button2 to a very large number, such as 2000, which can be seen in graphical layout mode with the full width of the button1 fill, And do not see the shadow of Button2, in fact, button2 still exist, you put the mouse pointer to the back of the button1 can see a long erector spinae, which is button2, is very very small. So, when Layout_width is set to Fill_parent, weight represents your control to be as big as possible.

Then, when Layout_weight is set to Wrap_content, that is, the width of the tolerance, which means that the control is as small as possible, as long as it can be displayed, the same, if the layout_ of Button1 and Button2 After weight was set to Wrap_content, Button1 's weight 1,button2 for weight was 2. Then button1 to be as small as possible, and button2 to be as small as possible, but the first grade is different, because the set up Weight, so the width of the two controls is filled with the width of the parent, so you have to calculate the size of each control, this time, the Button1 is higher, a total of two, a 1/3, a copy of the 2/3,button1 to be as small as possible, that button1 of course to choose 1/ 3, so the effect we see is rather larger than the button2 occupation. The thing to say here is that if you do the same thing, set the following: Button1 for 1,button2 2000, is the Button1 going to occupy 1/2000 of the space? So the understanding is wrong, just said, to be as small as possible, but this small there is a limit, that is wrap_content, is also if the full display of the whole, the same, as much as possible there is a limit, that is the width of the father's office. So, when Layout_width is set to Wrap_content, weight represents your control to be as big as possible.
So, to understand the weight, we must deeply understand the following two words:
when Layout_width is set to Fill_parent, Layout_weight represents your control to be as big as possible, but this is a big limit, that is, fill_parent.
When Layout_width is set to Wrap_content, Layout_weight represents your control to be as small as possible, but this small is limited, that is, wrap_content.

layout_height with Layout_width.



Finally put a few pictures to come out:
1. Layout_width= "Fill_parent", weight=2 of Button1 Weight=1,button2;




2.layout_width= "Fill_parent", the weight=2000 of Button1 Weight=1,button2;



3.layout_width= "Wrap_content", the weight=2 of Button1 Weight=1,button2;



4.layout_width= "Wrap_content", the weight=2000 of Button1 Weight=1,button2;

Reprint of the explanation ********* reprint address: http://hi.baidu.com/ljlkings/blog/item/fa2a59803f839a82f603a6b2.html?timeStamp=1305190390481

Explanations in the SDK

Indicates how much of the extra space in the linearlayout would be allocated to the view associated with these Lay Outparams. Specify 0 if the view should not being stretched. Otherwise the extra pixels would be a pro-ratedamong all views whose weight is greater than 0.

There are two key points, one is Layout_weight, which represents the division of additional space in the LinearLayout (which may be compressed before the extension application layout_weight), and the other is prorated.

The following is an example of android:orientation= "horizontal"

Look at the source code, although not very understand, but understand the next general meaning, in accordance with their own understanding summed up, directly write a simplified code bar (the following code is LinearLayout source file part of the simplification, variable name meaning may not be accurate, for the narrative convenient for this explanation):

Either expand children with weight to take up available space or//shrink them if they extend beyond we current BOUNDSI NT Delta = widthsize-mtotallength;if (Delta! = 0 && totalweight > 0.0f) {    float weightSum = mweightsum &G T 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;
            int childwidth = child.getmeasuredwidth () + share;            if (Childwidth < 0) {                childwidth = 0;            }        }    }}

Variable meaning

Width of the Widthsize:linearlayout

Mtotallength: The width of all sub-view and (also no consideration layout_weight)

Totalweight: Layout_weight of all sub-view and

The Android:weightsum property of Mweihtsum:linearlayout

Process Analysis:

The extra space is calculated first (can be negative) if the extra space is not 0 and the layout_weight with the child view is not 0, then the extra space is allocated by layout_weight:

int delta = widthsize-mtotallength;if (Delta! = 0 && totalweight > 0.0f) {  ...}

If LinearLayout set Weightsum, the and of the layout_weight of the child view is overwritten:

float WeightSum = mweightsum > 0.0f? Mweightsum:totalweight;

Then traverse the LinearLayout child element, if it is not null and visibility is not gone, obtain its layoutparams if its layout_weight is greater than 0, Calculates the extra space allocated to it based on the weightsum and its weight

if (Childextra > 0) {    int share = (int) (Childextra * delta/weightsum);   WeightSum-= Childextra; Delta-= share;    int childwidth = child.getmeasuredwidth () + share;    if (Childwidth < 0) {        childwidth = 0;    }}


There is an explanation on the Internet that layout_weight indicates the importance of dividing the priority of additional space, which can be known by code as wrong. Layout_weight represents the proportion of division, as for when View Layout_width is Fill_ The problem of the inverse ratio of layout_weight to the parent is explained in my understanding 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:lay Out_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_pa Rent "android:layout_height=" fill_parent "android:layout_weight=" 2 "android:text=" 3 "> </but Ton></linearlayout>



According to general understanding, the ratio of 3 buttons should be 1:1:2, but the reality is this:

As I understand it, the system sets the size of the button, and the variable name is the meaning of the preceding code:

Assume that container is the width of the linearlayout parent_width

The width of the three buttons is fill_parent, so three buttons have a width of parent_width before applying layout_width

So extra space Delta = parent_width-3 * Parent_width =-2 * PARENT

Because LinearLayout is not set Android:weightsum (default is 0, set to 0 is not set), so mweightsum = 1 + 1 +2 =4

So:

The first button has a width of parent_width + share = parent_width + (layout_weight * delta/mweightsum) = Parent_width + (1 * ( -2 * Parent_wid TH)/4) = *parent_width

WeightSum-= Childextra; (=3) delta-  = share; (=-3/2 * parent_width)

The second button has a width of parent_width + share = parent_width + (layout_weight * delta/mweightsum) = Parent_width + (1 * ( -3/2 * PARENT) _width)/3) = *parent_width

WeightSum-= Childextra; (=2) delta-  = share; (=-parent_width)

The third button has a width of parent_width + share = parent_width + (layout_weight * delta/mweightsum) = Parent_width + (2 * (-Parent_width) /2) = 0

So the final thing is that the first two buttons split LinearLayout, and the third button disappears.

The approximate process is this, but not all, for example, if the LinearLayout weightsum in the example above is set to 2, the first two buttons have a width of 0, but when the third button is calculated the width is mweightsum = 0, but layout_weight * Delta/ Mweightsum can not calculate, do not know how the system to deal with, in my ability, weightsum for 2 o'clock:

When Weightsum is 3:

As explained in the SDK, layout_weight indicates how extra space is divided, to note the extra 2 words, to have extra space to allocate it proportionally to the child view set Layout_weight, so if LinearLayout is set to WRAP_ Content words are no extra space, layout_weight is useless, as long as the layout_width is not set to wrap_content on the line, can also be set to a specific value, if the value is too small, the extra space is negative, may compress the child control, 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>

Additional Space Delta = 100-3 * 60 = 80

Mweightsum = 1 + 1 +2 =4

So:

The first button has a width of 60+ share = + (Layout_weight * delta/mweightsum) = 60 + (1 * (-80)/4) = 40

WeightSum-= Childextra; (=3) delta-  = share; (=-60)

The second button has a width of + share = + (Layout_weight * delta/mweightsum) = 60 + (1 * (-60)/3) = 40

WeightSum-= Childextra; (=2) delta-  = share; (=-40)

The third button has a width of four + share = + (Layout_weight * delta/mweightsum) = 60 + (2 * (-40)/2) = 20

:

The following code also shows that layout_weight represents the allocation of additional 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 the Button1 is 60+100/2=110,button2 40+100/2=90

Layout_weight Ultimate Research in Android

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.