Custom view is occasionally used in Android development, and in general, custom view needs to inherit the Onmeasure method of the view class, so why inherit the Onmeasure () function? Under what circumstances should inherit Onmeasure ()? What is the behavior of the system default Onmeasure () function? This article explores these questions.
First, we write a custom view that directly calls the system default Onmeasure function to see what happens:
| 12345678910111213141516171819202122 |
packagecom.titcktick.customview;importandroid.content.Context;import android.util.AttributeSet;importandroid.view.View;publicclassCustomView extendsView { publicCustomView(Context context) { super(context); } publicCustomView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protectedvoidonMeasure(intwidthMeasureSpec, intheightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); }} |
1. Parent controls use Match_parent,customview with Match_parent
| 12345678910111213 |
<LinearLayout 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:orientation="vertical"> <com.titcktick.customview.CustomView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10dp" android:background="@android:color/black"/></LinearLayout> |
This adds a margin of 10DP and sets the background of the view to black for easy identification of our CustomView, the effect is as follows:
As we can see, by default, CustomView fills the parent control if both the parent and CustomView use Match_parent.
2. Parent controls use Match_parent,customview with Wrap_content
Replace the CustomView layout_width/layout_height in the layout file with Wrap_content, and you will find that the result is still full of the parent control.
3. The parent control uses a fixed value with Match_parent,customview
Replace the CustomView layout_width/layout_height in the layout file with 50DP, and you will find that the CustomView display results are 50DPX50DP:
4. The parent control uses a fixed value, customview using Match_parent or Wrap_content
So, if you replace the parent control's layout_width/layout_height with 50dp,customview set to Match_parent or wrap_content, you will find that The CustomView display results are also for 50dpx50 DP.
5 Conclusion
If the custom CustomView takes the default Onmeasure function, the behavior is as follows:
(1) CustomView is set to match_parent or wrap_content without any difference, and its display size is determined by the parent control, which fills the space of the entire parent control.
(2) CustomView is set to a fixed value, its display size is the set value.
If your custom control's size calculation is consistent with the default behavior of the system, then you don't need to rewrite the onmeasure function.
6. How to write Onmeasure functions
The behavior of the system's default Onmeasure function is discussed here, and the following is how to rewrite the Onmeasure function, as well as the basic principle of onmeasure function, the key part in the code in the form of comments given, for reference only:
| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
packagecom.titcktick.customview;importandroid.content.Context;importandroid.util.AttributeSet;importandroid.view.View;publicclassCustomView extendsView { privatestaticfinal intDEFAULT_VIEW_WIDTH = 100; privatestaticfinalintDEFAULT_VIEW_HEIGHT = 100; publicCustomView(Context context) { super(context); } publicCustomView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protectedvoidonMeasure(intwidthMeasureSpec, intheightMeasureSpec) { intwidth = measureDimension(DEFAULT_VIEW_WIDTH, widthMeasureSpec); intheight = measureDimension(DEFAULT_VIEW_HEIGHT, heightMeasureSpec); setMeasuredDimension(width, height); } protectedintmeasureDimension( intdefaultSize, intmeasureSpec ) { intresult = defaultSize; intspecMode = MeasureSpec.getMode(measureSpec); intspecSize = MeasureSpec.getSize(measureSpec); //1. layout给出了确定的值,比如:100dp //2. layout使用的是match_parent,但父控件的size已经可以确定了,比如设置的是具体的值或者match_parent if(specMode == MeasureSpec.EXACTLY) { result = specSize; //建议:result直接使用确定值 } //1. layout使用的是wrap_content //2. layout使用的是match_parent,但父控件使用的是确定的值或者wrap_content elseif (specMode == MeasureSpec.AT_MOST) { result = Math.min(defaultSize, specSize); //建议:result不能大于specSize } //UNSPECIFIED,没有任何限制,所以可以设置任何大小 //多半出现在自定义的父控件的情况下,期望由自控件自行决定大小 else{ result = defaultSize; } returnresult; }} |
After overloading the Onmeasure function, you will find that when CustomView uses match_parent, it fills the entire parent control, and when CustomView uses Wrap_content, Its size is the default size defined in the code 100x100 pixels. Of course, you can also rewrite the implementation of Measuredimension () according to your own needs.
Android Development Practice: Why Inherit Onmeasure ()