Android custom View ------- why rewrite onMeasure () and how to rewrite it? androidonmeasure

Source: Internet
Author: User

Android custom View ------- why rewrite onMeasure () and how to rewrite it? androidonmeasure

I have read a lot of information about android custom components in the past two days. I still feel that I do not have a thorough understanding of the onMeasure () method, later, I knew how to use onMeasure, and wondered why I needed to implement onMeasure.


This article mainly records two problems: 1) when to implement the onMeasure () method for custom components, 2) How to Implement the onMeasure () method


Why do I need to implement the onMeasure () method?


Let's take a look at the following example. We define a View by ourselves, which is very simple, just inheriting the View class.

public class MyView extends View {public MyView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);// TODO Auto-generated constructor stub}public MyView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}public MyView(Context context) {super(context);// TODO Auto-generated constructor stub}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubsuper.onMeasure(widthMeasureSpec, heightMeasureSpec);}}

Then define the following layout in the layout file:

<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" xmlns: tools = "http://schemas.android.com/tools" xmlns: MyView = "http://schemas.android.com/apk/res/com.notes.notes_onmeasure" android: layout_width = "match_parent" android: layout_height = "match_parent" android: orientation = "vertical" android: padding = "@ dimen/activity_vertical_margin" tools: context = "com. notes. notes_onmeasure.EasyActivi Ty "> <com. notes. notes_onmeasure.MyView android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: background = "#78787878"/> <TextView android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: text = "can you see me? "/> </LinearLayout>


The result is displayed as shown in Figure


When the width and height of MyView are set to match_parent, MyView will fill the entire interface without any doubt. When the width and height are set to a specific value, the size of MyView is also displayed according to the specified value. However, in the above example, we set the width and height of MyView to wrap_content, which still fills the entire interface. The problem lies here, so we need to override the onMeasure () method to control its size. Other components inherited from View, such as Button and TextView, have been rewritten by the onMeasuer () method.


How to override the onMeasure () method

In android, the size of each View depends not only on itself, but also on the parent View. For details, refer to How Android Draws Views on the Android page of my other article. OnMeasure () is called when the child view is computed in the parent view. The details are not described here. We only need to do this for the time being.

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {       //,,,    }

The onMeasure () method has two parameters, which are the constraints that the parent view sends to the Child view. We will directly rewrite the onMeasure () method in the above MyView and use an example to understand how the onMeasure () method is implemented.


@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubsuper.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = measureDimension(200, widthMeasureSpec);int height = measureDimension(200, heightMeasureSpec);setMeasuredDimension(width, height);}public int measureDimension(int defaultSize, int measureSpec){int result;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);if(specMode == MeasureSpec.EXACTLY){result = specSize;}else{result = defaultSize;   //UNSPECIFIEDif(specMode == MeasureSpec.AT_MOST){result = Math.min(result, specSize);}}return result;}

When you override the onMeasure () method, you must call the setMeasureDimension () method. Otherwise, an error is returned. Then, how do we calculate the width and height of setMeasureDimension?


First, we will parse widthMeasureSpec to get two pieces of data. One is the size of the parent view, and the other is the size mode. The two pieces of data are obtained by the following two pieces of code:


      int specMode = MeasureSpec.getMode(measureSpec);      int specSize = MeasureSpec.getSize(measureSpec);

The MeasureSpec. getMode () method returns three results:

  • UNSPECIFIED: the size of the child node of the parent node is not required.
  • EXACTLY: the parent node requires the size of its child nodes to be specified as an exact value. The child nodes and other child nodes must be adapted to this size.
  • At most: the parent node requires that the size of its child nodes cannot exceed a certain maximum value. The size of its child nodes and other child nodes must be smaller than this value.


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.