Inherit the ViewGroup learning onMeasure () and onLayout () methods, viewgrouponmeasure

Source: Internet
Author: User

Inherit the ViewGroup learning onMeasure () and onLayout () methods, viewgrouponmeasure

When inheriting the ViewGroup class, you must override two methods: onMeasure and onLayout.

1. Call the setMeasuredDimension method void android. view. View. setMeasuredDimension (int measuredWidth, int measuredHeight) in the onMeasure method)
In onMeasure (int, int), you must call setMeasuredDimension (int width, int height) to store the width and height of the measurement. If you do not do so, an exception IllegalStateException is triggered.
2. Call the child's measure Method in method onMeasure.

Void android. view. View. measure (int widthMeasureSpec, int heightMeasureSpec)

This method is used to measure the view size. The parent view uses the width and height parameters to provide constraint information. In fact, the measurement of view is completed in the onMeasure (int, int) method. Therefore, only the onMeasure (int, int) method can and must be overwritten. The widthMeasureSpec parameter provides the horizontal space specification of the view, and the heightMeasureSpec parameter provides the vertical space specification of the view.

3. parse the onMeasure (int, int) Method

Void android. view. View. onMeasure (int widthMeasureSpec, int heightMeasureSpec)

Measure the view and its content to determine the width and height of the view. This method is called in measure (int, int) and must be overwritten to accurately and effectively measure the view content.

When rewriting this method, you must call setMeasuredDimension (int, int) to store the measured width and height values. If the execution fails, an IllegalStateException is triggered. OnMeasure (int, int) of the parent view is valid.

By default, the basic measurement data of a view takes its background size unless a larger size is allowed. The child view must override onMeasure (int, int) to provide a more accurate measurement value. If overwritten, The subclass ensures that the measured height and width are at least the smallest height and width of the view (obtained through getSuggestedMinimumHeight () and getSuggestedMinimumWidth ).

4. parse the onLayout (boolean, int, int) method.

Void android. view. ViewGroup. onLayout (boolean changed, int l, int t, int r, int B)

Call scenario: it is called when the view sets the size and position for the child. Child view, including child, must overwrite the onLayout (boolean, int) method and call their respective layout (int, int) methods.

Parameter description: The changed parameter indicates that the view has a new size or position. The l parameter indicates the Left position relative to the parent view. The t parameter indicates the Top position relative to the parent view; parameter r indicates the Right position relative to the parent view; parameter B indicates the Bottom position relative to the parent view ..

5. parse the View. MeasureSpec class
Android. view. View. MeasureSpec
The MeasureSpec object encapsulates the layout Specification Description and passes it from the parent view to the Child view. Each MeasureSpec object represents the width or height specification.
The MeasureSpec object contains a size and a mode. The mode can take one of the following three values:
UNSPECIFIED, 1073741824 [0x40000000]. If no rule is added, no rule is added to the subview.
EXACTLY, 0 [0x0], which indicates that the parent view determines the exact size for the Child view.
AT_MOST,-2147483648 [0x80000000]. The child view can be as large as possible within the specified size.


Here is an example demo:
Step 1: Customize a View to implement the ViewGroup interface, that is, customize the ViewGroup:

Import android. content. context; import android. util. attributeSet; import android. view. view; import android. view. viewGroup; public class MyViewGroup extends ViewGroup {public MyViewGroup (Context context) {super (context);} public MyViewGroup (Context context, AttributeSet attrs) {super (context, attrs );} public MyViewGroup (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, DefStyle);}/*** calculate the widget size */@ Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {super. onMeasure (widthMeasureSpec, rule); int measureWidth = measureWidth (widthMeasureSpec); int measureHeight = measureHeight (heightMeasureSpec); // calculates the size of all sub-controls in the Custom ViewGroup, heightMeasureSpec); // set the size of the custom control MyViewGroup setMeasuredDimension (MeasureWidth, measureHeight);} private int measureWidth (int pWidthMeasureSpec) {int result = 0; int widthMode = MeasureSpec. getMode (pWidthMeasureSpec); // get the mode int widthSize = MeasureSpec. getSize (pWidthMeasureSpec); // you can obtain the size switch (widthMode) {/*** mode. The values are MeasureSpec. UNSPECIFIED, MeasureSpec. EXACTLY, * MeasureSpec. AT_MOST. * ** MeasureSpec. EXACTLY is the exact size. * When we specify the layout_width or layout_height of the control as a specific value, for example, andorid *: layout_width = "50dip", or FILL_PARENT is, when the control size is determined, they are precise dimensions. * ** MeasureSpec. AT_MOST is the maximum size. * When the layout_width or layout_height of the control is set to WRAP_CONTENT *, the control Size usually changes with the control's sub-spaces or content, in this case, the widget size must not exceed the maximum size allowed by the parent widget *. Therefore, the mode is AT_MOST, and size provides the maximum size allowed by the parent control. * ** MeasureSpec. UNSPECIFIED indicates that the size is not specified. In this case, the parent control is generally AdapterView. * The mode passed in through the measure method. */Case MeasureSpec. AT_MOST: case MeasureSpec. EXACTLY: result = widthSize; break;} return result;} private int measureHeight (int pHeightMeasureSpec) {int result = 0; int heightMode = MeasureSpec. getMode (pHeightMeasureSpec); int heightSize = MeasureSpec. getSize (pHeightMeasureSpec); switch (heightMode) {case MeasureSpec. AT_MOST: case MeasureSpec. EXACTLY: result = heightSize; break;} return result;}/*** overwrites onLayout to specify the display position of the view, the order before and after method execution is after onMeasure, because the view must know the size, * can determine how to place the view */@ Override protected void onLayout (boolean changed, int l, int t, int r, int B) {// total record height int mTotalHeight = 0; // traverse all subviews int childCount = getChildCount (); for (int I = 0; I <childCount; I ++) {View childView = getChildAt (I); // obtain the View Size int measureHeight = childView in onMeasure. getMeasuredHeight (); int measuredWidth = childView. getMeasuredWidth (); childView. layout (l, mTotalHeight, measuredWidth, mTotalHeight + measureHeight); mTotalHeight + = measureHeight ;}}}

Step 2: layout the file:

<RelativeLayout xmlns: android = "http://schemas.android.com/apk/res/android" xmlns: tools = "http://schemas.android.com/tools" android: layout_width = "match_parent" android: layout_height = "match_parent" android: background = "#00f0f0" tools: context = ". mainActivity "> <net. loonggg. viewgroup. myViewGroup android: id = "@ + id/myViewGroup" android: layout_width = "480dp" android: layout_height = "300dp" android: background = "# 0f0f"> <TextView android: layout_width = "200dp" android: layout_height = "100dp" android: background = "#000000" android: gravity = "center" android: text = "first TextView"/> <TextView android: layout_width = "100dp" android: layout_height = "200dp" android: background = "# ffffff" android: gravity = "center" android: text = "second TextView"/> </net. loonggg. viewgroup. myViewGroup> </RelativeLayout>

  

Related Article

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.