Note: According to the online information organized as follows
The first Onmeasure method is to get the function of each view size
Fill_parent-->public static final int exactly = 1 << mode_shift;
Wrap_content-->public static final int at_most = 2 << mode_shift;
This is the code snippet for the Makemeasurespec method
Public Static int makemeasurespec (intint mode) { if ( Susebrokenmakemeasurespec) { return size + mode; Else { return (Size & ~mode_mask) | (Mode & mode_mask); } }
Where the default value for Susebrokenmakemeasurespec is false:
/** * Use the old (broken) building measurespecs. */ Private Static Boolean false;
Let's take a look at Susebrokenmakemeasurespec related code
1 PublicView (Context context) {2The irrelevant code is omitted here ... - - if(!scompatibilitydone && Context! =NULL) { + Final intTargetsdkversion =context.getapplicationinfo (). targetsdkversion; - + //older apps may need this compatibility hack for measurement. ASusebrokenmakemeasurespec = Targetsdkversion <=JELLY_BEAN_MR1; at - //older apps expect onmeasure () to always being called on a layout pass, regardless - //of whether a layout was requested on the that View. -Signoremeasurecache = Targetsdkversion <KITKAT; - -Scompatibilitydone =true; in } -}
In the construction method, the value of Susebrokenmakemeasurespec is judged, and the code goes into line 18th and there is a scompatibilitydone,
The original default value is False, so when the view is initialized, it will go into this line, when the SDK version is less than jelly_bean_mr1 , which is 4.2, will return true,
Okay, now look back. 4.2 Version or the Makemeasurespec return value is size + MODE after the version is (Size & ~mode_mask) | (Mode & mode_mask).
Now, let's talk about the important methods in Measurespec.
//The Carry size is 2 of the 30 square (the size of int is 32 bits, so the carry 30 bit is to use the highest bit of int and the second-to-last digit is 32 and 31 bits to do the flag bit) Private Static Final intMode_shift = 30; //operation Matte, 0x3 is 16, 10 binary is 3, binary is 11. 3 left carry 30, that is 11 00000000000 (11 followed by 30 0)//(The effect of the mask is to use 1 to annotate the desired value, and 0 to label the unwanted value.) Because 1 and any number do and operations are any number, 0 and any number do and operations are 0) Private Static Final intMode_mask = 0x3 <<Mode_shift; //0 left carry 30, that is 00 00000000000 (00 followed by 30 0) Public Static Final intUNSPECIFIED = 0 <<Mode_shift; //1 left carry 30, that is 01 00000000000 (01 followed by 30 0) Public Static Final intexactly = 1 <<Mode_shift; //2 left carry 30, that is 10 00000000000 (10 followed by 30 0) Public Static Final intAt_most = 2 <<Mode_shift; /*** Get a detailed measurement result based on the size and mode provided*/ //measurespec = size + mode; (Note: binary addition, not 10-binary addition!) ) //The purpose of this design is to use a 32-bit binary number, 32 and 31 bits to represent the value of mode, and the last 30 bits to represent the value of size//For example size=100 (4), Mode=at_most, then measurespec=100+10000...00=10000..00100
Note: The latest version of the SDK Makemeasurespec method at the beginning of the article, but read the previous article believe that understanding is not difficult Public Static intMakemeasurespec (intSizeintmode) { returnSize +mode; } /*** Get mode with detailed measurement results*/ //mode = Measurespec & mode_mask; //Mode_mask = 11 00000000000 (11 followed by 30 0), the principle is to replace the 30-bit 0 in the post-mode_mask 30 bit with 1 in the post-Measurespec, and then retain the MODE value of 32 and 31 bits. //For example, 00..00100 & 11 00..00 (11 followed by 30 0) = 00..00 (At_most), which gives the value of mode Public Static intGetMode (intMeasurespec) { return(Measurespec &mode_mask); } /*** Get size with detailed measurement results*/ //size = Measurespec & ~mode_mask; //The principle is the same as above, but this time is to reverse the mode_mask, that is, 00 111111 (00 followed by 30 1), 32, 31 is replaced by 0 is to remove mode, retain the 30 bit size Public Static intGetSize (intMeasurespec) { return(Measurespec & ~mode_mask); }