在讲解之前,我谈谈开发Android一年多以来的感受:大多数情况下只要会用,根本不管为什么要这么写,原理就更不会看了。代码真的很乱,没有规范,很多时候自己写的代码都不知道怎么改。就更别说扩展,复用,抽象。虽然做了6,7个项目,但真正踏实学到的东西不多。你呢?有何感想?
来看看下面2张自定义的View:
如果你经常玩游戏,在人物创建的界面会看到相似的图片,在Android应用中我基本没看到。只是通过对它的制作过程来讲解下怎么去实现自定义View。
在自定义View控件的时候会经常用到 xxTo,可能你分不清楚,下面我们来看看moveTo、lineTo、quadTo、cubicTo、arcTo到底有什么作用。
moveTo 不会进行绘制,只用于移动移动画笔。
lineTo 用于进行直线绘制。
mPath.lineTo(500, 500);
canvas.drawPath(mPath, mPaint);
效果如图:
那我们加上moveTo:
mPath.moveTo(200,200);
mPath.lineTo(500, 500);
canvas.drawPath(mPath, mPaint);
quadTo 用于绘制圆滑曲线,即贝塞尔曲线。
mPath.quadTo(x1, y1, x2, y2)其中 (x1,y1) 为控制点,(x2,y2)为结束点。
mPath.moveTo(100, 500);
mPath.quadTo(300, 200, 800, 500);
canvas.drawPath(mPath, mPaint);
cubicTo 同样是用来实现贝塞尔曲线的。
mPath.cubicTo(x1, y1, x2, y2, x3, y3) 其中(x1,y1) 为控制点,(x2,y2)为控制点,(x3,y3) 为结束点。
mPath.moveTo(100, 500);
mPath.cubicTo(100, 500,300, 200, 800, 500);
canvas.drawPath(mPath, mPaint);
和上面的quadTo一样的效果,如果我们不加moveTo呢?
mPath.cubicTo(100, 500,300, 200, 800, 500);
canvas.drawPath(mPath, mPaint);
arcTo 用于绘制弧线(实际是截取圆或椭圆的一部分)。
mPath.arcTo(ovalRectF, startAngle, sweepAngle) , ovalRectF为椭圆的矩形,startAngle 为开始角度,sweepAngle 为结束角度。顺时针旋转
RectF mRectF = new RectF(10, 10, 600, 600);
mPath.arcTo(mRectF, 0, 90);
canvas.drawPath(mPath, mPaint);
如果属性是wrap_content,我们就取屏幕宽度与屏幕高度的较小值。
if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
heightSpecSize = widthSpecSize = getDefaultWidth();
setMeasuredDimension(widthSpecSize, heightSpecSize);
} else if (widthSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(getDefaultWidth(), heightSpecSize);
} else if (heightSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(widthSpecSize, getDefaultWidth());
}
首先我们来画正几边行:
我们这里要用到cos函数和sin函数,计算每个拐角的坐标
float x = (float) (centerPointX + radius * Math.cos(Math.toRadians(angle * i)));
float y = (float) (centerPointY + radius * Math.sin(Math.toRadians(angle * i)));
后面我会提供源码下载。
如果你想多画几个不同多边形,只需要循环改变【radius 】的值。
然后就是画轴线:
//绘制轴线
for (int i = 1; i < arrCount + 1; i++) {
mPath.reset();
mPath.moveTo(centerPointX, centerPointY);
float x = (float) (centerPointX + radius * Math.cos(Math.toRadians(angle * i)));
float y = (float) (centerPointY + radius * Math.sin(Math.toRadians(angle * i)));
mPath.lineTo(x, y);
canvas.drawPath(mPath, netPaint);
}
看到这里覆盖物,文本的绘制,你也可以轻松的实现。你可以参考github地址