1、自定义ViewGroup
- OnLayout
- OnMeasure
- OnTouch
- OnDraw
- Custom Attributes
onLayout
/**
*
* @param changed
* @param left 当前控件左上x坐标
* @param top 当前控件左上y坐标
* @param right 当前控件右下x坐标
* @param bottom 当前控件右下y坐标
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int count = getChildCount(); //孩子个数
int itemWidth = (right - left) / count ; //每个孩子的宽度
for(int i = 0 ;i<count;i++){
int cl = itemWidth * i ;
int ct = 0 ;
int cr = itemWidth * (i+1) ;
int cb = bottom - top ;
getChildAt(i).layout(cl,ct,cr,cb);
}
}
onMeasure
通过工具类MeasueSpec测量的宽和高(view:当前自定义控件的宽和高,viewgroup:测量自己外还需要遍历子view测量),最后记得调用setMeasuredDimensions(),
如果调用了super.onMeasure(widthMeasureSpec,heightMeasureSpec);其内部调用如下:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
此处需要注意MeasureSpec.getSize()和 getHeight()的区别,前者为自定义控件的原始高度,后者为该控件在屏幕上显示的高度。
onTouch
........
onDraw
eg:画一个白色背景的蓝色圆
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int x = getWidth();
int y = getHeight();
int radius;
radius = x/4;
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
canvas.drawPaint(paint);
paint.setColor(Color.BLUE);
canvas.drawCircle(x/2,y/2,radius,paint);
}
实现onDraw方法获取到的Cavas对象可以画很多东西,例如:
. drawLine
. drawRect
. drawCircle
. drawPath
. drawText
. drawBitmap
. drawOval
Custom Attributes
1、values文件夹下创建xml文件,例如:attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustmView">
<attr name="itmeWidth" format="dimension"/>
</declare-styleable>
</resources>
2、构造方法中获取
public class CustmView extends ViewGroup {
public CustmView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CustmView);
float itemWidth = typedArray.getDimension(R.styleable.CustmView_itmeWidth, 100f);
}
3、应用你获取到的值,如itemWidth可在onDraw方法中使用
其他
通常为了方便使用,自定义控件中会定义一些Setter和Getter,其中可能会重绘和重新布局,
例如改变了某个参数后,可能会调用
invalidate(); //Re-draw
requestLayout();//Re-layout