您的位置:首页 > 移动开发 > Android开发

Android 学习之--自定义ViewGroup

2013-07-04 15:30 435 查看

简介:

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: