Andrid 自定义View

1、绘制顺序及相关原理

http://orgcent.com/android-custom-view-draw-mechanism/

@Override  

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  

    int width = MeasureSpec.getSize(widthMeasureSpec);   //获取ViewGroup宽度  

    int height = MeasureSpec.getSize(heightMeasureSpec);  //获取ViewGroup高度  

    setMeasuredDimension(width, height);    //设置ViewGroup的宽高  

    int childCount = getChildCount();   //获得子View的个数,下面遍历这些子View设置宽高  

    for (int i = 0; i < childCount; i++) {  

        View child = getChildAt(i);  

            child.measure(viewWidth, viewHeight);  //设置子View宽高  

        }  

 }


@Override    

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {    

    int mTotalHeight = 0;    

    // 当然,也是遍历子View,每个都要告诉ViewGroup    

    int childCount = getChildCount();    

    for (int i = 0; i < childCount; i++) {    

        View childView = getChildAt(i);    

        // 获取在onMeasure中计算的视图尺寸    

        int measureHeight = childView.getMeasuredHeight();    

        int measuredWidth = childView.getMeasuredWidth();    

        childView.layout(left, mTotalHeight, measuredWidth, mTotalHeight + measureHeight);        

        mTotalHeight += measureHeight;    

    }    

}

2、 setXfermode 中的 src,dst如何理解:

// 绘制前景图  ,新画上去的图片可以理解为前景,就是src。

paint = new Paint();

paint.setColor(Color.WHITE);

paint.setAntiAlias(true);

paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));

 // 绘制背景图  ,canvas原有的图片可以理解为背景,就是dst;

paint2 = new Paint();

paint2.setXfermode(null);

3、Rect(left,top,right,bottom)参数的意思:

Rect参数的意思代表的是矩形的左上角的坐标(left、top)和右下角的坐标(right、bottom)
由两点的位置确定了矩形的高和宽
高:bottom-top
宽:right-left

4、drawArc()方法参数的意思:

public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

  • oval :指定圆弧的外轮廓矩形区域。

  • startAngle: 圆弧起始角度,单位为度。

  • sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度。

  • useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。

  • paint: 绘制圆弧的画板属性,如颜色,是否填充等。

5、为什么需要在TypedArray后调用recycle()方法:

当recycle被调用后,这就说明这个对象从现在可以被重用了。

原文地址:http://www.cnblogs.com/kissazi2/p/4049982.html 

6、绘制时钟

原理说明:http://www.haodaima.net/art/2603825   讲的好!

  绘制刻度

最复杂的地方就是画刻度了,这里要先复习一下数学中的三角函数:

Andrid 自定义View_第1张图片

刻度的起始位置就是圆框上的一个点,第一步就是要知道这个点的坐标。上图中:

sinθ = AC / AO
cosθ = OC / AO

其中AO即为圆半径,而θ的值则根据刻度而定。0是π/2,3是0,6是3π/2,9是π:

Andrid 自定义View_第2张图片

由此可得到刻度起始点的位置为:

x = 圆点横坐标 + AO * cosθ
y = 圆点纵坐标 + AO * sinθ

同理可算出刻度结束点的位置为(结束点相当于在一个半径为圆框半径-刻度长度的圆上):

x = 圆点横坐标 + (AO - 刻度长度) * cosθ
y = 圆点纵坐标 + (AO - 刻度长度) * sinθ

于是,这程序可以写了:

for (var i = 0, angle = 0, tmp, len; i < 60; i++) {
bgCtx.beginPath();

// 突出显示能被5除尽的刻度
if (0 === i % 5) {
bgCtx.lineWidth = 5;
len = 12;
bgCtx.strokeStyle = '#000';
} else {
bgCtx.lineWidth = 2;
len = 6;
bgCtx.strokeStyle = '#999';
}

tmp = radius - borderWidth / 2; // 因为圆有边框,所以要减去边框宽度
bgCtx.moveTo(
dot.x + tmp * Math.cos(angle),
dot.y + tmp * Math.sin(angle)
);
tmp -= len;
bgCtx.lineTo(dot.x + tmp * Math.cos(angle), dot.y + tmp * Math.sin(angle));
bgCtx.stroke();
bgCtx.closePath();

angle += Math.PI / 30; // 每次递增1/30π
}

正玄定理余玄定理回顾:http://baike.baidu.com/link?url=a2JC6gyPPQh2ZOQ6UJjrcpvNeaG6mPeXLWVoix6u7E3FhOG4NynGdTyl61VosvO4

7、android中path的arcTo方法的使用:

该方法的声明为:

void android.graphics.Path.arcTo(RectF oval, float startAngle, float sweepAngle);

该方法是画一个弧线的路径.

第一个参数是一个RectF类型.这个参数是干嘛的呢?

先说一下,这个弧线是怎么来的?是先画一个椭圆,然后再在这个椭圆上面截取一部分部形。这个图形自然就是一个弧线了。那么这个椭圆是怎么确定的呢?这就是这个rectF参数所起的作用了。

如图所示:

Andrid 自定义View_第3张图片

给出这个矩形后,系统就可以算出这个矩形的中心,然后以这个矩开的中心画一个椭圆。

得到这个椭圆后,然后就是截取一部分线了,就得到最终的弧线。这一部分是怎么截取的呢?

这就是后面两个参数共同来表达的。

startAngle这个参数说的是开始的角度。这个好理解,但哪里是0度线呢,又是向哪个方向旋转是正角度数呢?下面由图形来展示:

Andrid 自定义View_第4张图片

图上所示的红线就是0度线。

startAngle是开始度数,那sweepAngle是指的什么呢?

sweepAngle指的是旋转的度数,也就是以startAngle开始,旋转多少度,如果sweepAngle是正数,那么就是按顺时针方向旋转,如果是负数就是按逆时针方向旋转。

如果示例:startAngle = 0; sweepAngle=90:

Andrid 自定义View_第5张图片

红色部分的弧线就是最终的弧线...


8、canvas变换与操作:


Andrid 自定义View_第6张图片

Andrid 自定义View_第7张图片


http://blog.csdn.net/harvic880925/article/details/39080931



你可能感兴趣的:(Andrid 自定义View)