Android学习自定义View(五)——自定义ViewGroup及其onMeasure()的理解
发布日期:2021-06-30 11:14:23 浏览次数:2 分类:技术文章

本文共 4267 字,大约阅读时间需要 14 分钟。

MainActivity如下:
package cc.testviewstudy5;import android.os.Bundle;import android.app.Activity;/** * Demo描述: * 自定义ViewGroup及其onMeasure()的理解 *  * 参考资料: * 1 http://blog.csdn.net/guolin_blog/article/details/16330267 * 2 http://blog.csdn.net/dawanganban/article/details/23953827 *   Thank you very much */public class MainActivity extends Activity {	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(new ViewGroupSubClass(this));	}}
ViewGroupSubClass如下:
package cc.testviewstudy5;import android.content.Context;import android.graphics.Canvas;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import android.widget.Button;/** * 当继承自ViewGroup时,如果在onMeasure()对于子View不调用 * 1 measureChild(child, parentWidthMeasureSpec, parentHeightMeasureSpec) * 2 childView.measure(childWidthMeasureSpec, childHeightMeasureSpec) * 这两个方法的任何其中一个,那么: * childView.getMeasuredWidth()和childView.getMeasuredHeight()得到的值均为0 *  * 这是为什么呢? * 因为ViewGroup继承自View,View就根本没有子View.所以: * 在ViewGroup的onMeasure()中的super.onMeasure(widthMeasureSpec,heightMeasureSpec) * 只是测量该ViewGroup本身的宽和高.而没有去测量其每个子View的宽和高. * 于是需要我们自己写代码去测量该ViewGroup的每个子View,或者让子View自己调用measure().这么操作以后,再用 * childView.getMeasuredWidth()和childView.getMeasuredHeight() * 得到的值就不再是0了. *  * 假若不继承自ViewGroup而继承自XXXLayout,那么就不是必须要自己去测量每个子View的大小了. * 查看XXXLayout的源代码,可以看到在其onMeasure()中已经测量了子View的大小. * */public class ViewGroupSubClass extends ViewGroup {	public ViewGroupSubClass(Context context) {		super(context);		Button button1 = new Button(context);		button1.setText("button1");		this.addView(button1);		Button button2 = new Button(context);		button2.setText("button2");		this.addView(button2);		Button button3 = new Button(context);		button3.setText("button3");		this.addView(button3);	}	public ViewGroupSubClass(Context context, AttributeSet attrs) {		super(context, attrs);	}	public ViewGroupSubClass(Context context, AttributeSet attrs, int defStyle) {		super(context, attrs, defStyle);	}	@Override	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {		super.onMeasure(widthMeasureSpec, heightMeasureSpec);		// 获取系统自动测量的该ViewGroup的大小		int widthSize = MeasureSpec.getSize(widthMeasureSpec);		int heightSize = MeasureSpec.getSize(heightMeasureSpec);		System.out.println("获取系统自动测量的该ViewGroup的大小: widthSize="+widthSize+",heightSize="+heightSize);		// 我们也可调用setMeasuredDimension()重新设置测量结果		// 修改了系统自动测量的子View的大小		int childCount = this.getChildCount();		int childMeasuredWidth = 0;		int childMeasuredHeight = 0;		int childWidthMeasureSpec = 0;		int childHeightMeasureSpec = 0;		for (int i = 0; i < childCount; i++) {			View childView = getChildAt(i);			// 系统自动测量子View:			measureChild(childView, widthMeasureSpec, heightMeasureSpec);			// 如果不希望系统自动测量子View,我们用以下的方式:			// childWidthMeasureSpec =			// MeasureSpec.makeMeasureSpec(100,MeasureSpec.EXACTLY);			// childHeightMeasureSpec =			// MeasureSpec.makeMeasureSpec(100,MeasureSpec.EXACTLY);			// childView.measure(childWidthMeasureSpec, childHeightMeasureSpec);		}		// 获取每个子View测量所得的宽和高		for (int i = 0; i < childCount; i++) {			View childView = getChildAt(i);			childMeasuredWidth = childView.getMeasuredWidth();			childMeasuredHeight = childView.getMeasuredHeight();			System.out.println("i=" + i+ ",获取系统自动测量的该子View的大小:" +					          "childMeasuredWidth="+ childMeasuredWidth + "," +					          "childMeasuredHeight="+ childMeasuredHeight);		}	}	@Override	protected void onLayout(boolean arg0, int l, int t, int r, int b) {		System.out.println("该ViewGroup的布局:"+"l="+l+",t="+t+",r="+r+",b="+b);		int childCount = getChildCount();		int left = 0;		int top = 10;		int right = 0;		int bottom = 0;		for (int i = 0; i < childCount; i++) {			View childView = getChildAt(i);			right = left + childView.getMeasuredWidth();			// 也可不用测量所得的宽而指定一个值			// right=left+180;			bottom = top + childView.getMeasuredHeight();			// 也可不用测量所得的高而指定一个值			// bottom=top+180;			childView.layout(left, top, right, bottom);			System.out.println("i=" + i + ",该子View的布局:" + "" +					          "left="+left+",top="+top+",right="+right+",bottom="+bottom);			top += 190;		}	}	@Override	protected void onDraw(Canvas canvas) {		super.onDraw(canvas);	}}
main.xml如下:
PS:
main.mxl没有任何用处

转载地址:https://it9527.blog.csdn.net/article/details/18911569 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Android学习自定义View(四)——继承控件(滑动时ListView的Item出现删除按钮)
下一篇:Android中AutoCompleteTextView完整示例(一)

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月18日 19时19分40秒