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.