Android 学习之--自定义ViewGroup

简介:

ViewGroup是一种可以包含其他视图的特殊视图,是布局和其他视图容器的基类。也就是别的基本的View或ViewGroup组件能够,放在里面。

一、onMeasure 

    测量View树上的各个View的大小.

 1、设置本View视图的最终大小,该功能的实现通过调用setMeasuredDimension()方法去设置实际的高(对应属    性: mMeasuredHeight)和宽(对应属性:mMeasureWidth)   ;
 2 、如果该View对象是个ViewGroup类型,需要重写该onMeasure()方法,对其子视图进行遍历的measure()过程。

测量这个View的大小。这个方法被调用通过measure(int, int) ,并且,它应当被它的子类所overriden ,和为它的COntent提供一个精确而有效的尺寸。
CONTRACT: 当overriding 这个方法的时候,你必须调用 call setMeasuredDimension(int, int) ,以便存储测量View的width和height。
 Failure to do so will trigger an IllegalStateException, thrown by measure(int, int). Calling the superclass' onMeasure(int, int) is a valid use

二、layout

     通过View树上 view节点的大小和View的位置,将View放置,在ViewGroup上面合适的位置。

代码实现:

public class MyViewGroup extends ViewGroup{
public static final String TAG="MyViewGroup";
	
	Context context;

	public MyViewGroup(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		this.context=context;
		init();
		Log.i(TAG, ">>>");
	}

	public MyViewGroup(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		this.context=context;
		init();
	}

	public MyViewGroup(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		
		this.context=context;
		init();
	}
	/**
	 * 初始化界面
	 */
	private void init() {
		// TODO Auto-generated method stub
		Button button=new Button(context);
//		button.measure(60, 60);
		
		button.setText("HHHH");
		
		ImageView imageView=new ImageView(context);
//		imageView.measure(80, 80);
		imageView.setBackgroundResource(R.drawable.ic_launcher);
		
		this.addView(button);
		this.addView(imageView);
		
	}
	@Override
		protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
			// TODO Auto-generated method stub
			super.onMeasure(widthMeasureSpec, heightMeasureSpec);
			int childCount = getChildCount() ;
//			
			int specSize_Widht = MeasureSpec.getSize(widthMeasureSpec) ;
	    	int specSize_Heigth = MeasureSpec.getSize(heightMeasureSpec) ;
	    	
//	    	//设置本ViewGroup的宽高
	    	setMeasuredDimension(specSize_Widht , specSize_Heigth) ;
	    	
	    	for (int i = 0; i < childCount; i++) {
				View childView=getChildAt(i);
				childView.measure(50, 60);
			}
			
			
			
		}
	@Override
	//对每个子View视图进行布局
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		// TODO Auto-generated method stub
    	//通过init()方法,我们为该ViewGroup对象添加了三个视图 , Button、 ImageView、TextView
    	int childCount = getChildCount() ;
//    	getViewGropSize();
    	int startLeft = 0 ;//设置每个子View的起始横坐标 
    	int startTop = 10 ; //每个子View距离父视图的位置 , 简单设置为10px吧 。 可以理解为 android:margin=10px ;
		Log.i(TAG, "**** onLayout start ****"+l+" "+t+" "+r+" "+b) ;

    	Log.i(TAG, "**** onLayout start ****") ;
    	/**
    	 * 对么个控件的布局的位置进行设置
    	 */
    	for(int i=0 ;i<childCount ; i++){
    		View child = getChildAt(i) ;   //获得每个对象的引用
    		child.layout(startLeft, startTop, startLeft+child.getMeasuredWidth(), startTop+child.getMeasuredHeight()) ;
    	startTop=startTop+child.getMeasuredHeight();// 
    	}   	   	
	}

	@Override
	protected void dispatchDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.dispatchDraw(canvas);
		
		Log.i(TAG, "dispatchDraw"+canvas.getWidth()+" "+canvas.getHeight());
	}

	@Override//对每个View节点进行绘制
	protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
		// TODO Auto-generated method stub
		Log.i(TAG, "drawChild"+canvas.getWidth()+" "+canvas.getHeight()+".."+drawingTime);
		return super.drawChild(canvas, child, drawingTime);
	}


}

在上面有canvas这个的地方,可以对其范围内,可以绘制任何图形。

如,把上面的代码更改:

@Override
	protected void dispatchDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.dispatchDraw(canvas);
		
		Paint mPaint=new Paint();
		mPaint.setColor(Color.BLUE);
		Rect r=new Rect(10, 20, 300, 500);
		canvas.drawRect(r, mPaint);
		
		Log.i(TAG, "dispatchDraw"+canvas.getWidth()+" "+canvas.getHeight());
	}

就可以在界面中看见自己所绘制的矩形。



参考:

http://blog.csdn.net/qinjuning/article/details/7110211


http://developer.android.com/reference/android/view/ViewGroup.html


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值