样式
控件分析:
线条分为3种
1.普通小线条;2每隔30°会绘制一个关键线条;3中间上部不变的指针
文字分为3种
1.边缘的度数标尺;2.方向标尺;3当前度数;4.当前方向
绘制思路:
- 绘制线条
先绘制普通小线条,默认有120条 ,如果能绘制1条,那么根据坐标旋转公式就能算出其余线条的位置,所以先绘制最左边的小线条
(80, height / 2) to ( 80+width * lineRateSize,height/2)
这样就绘制好一条直线(即270°的横线);
之后根据旋转公式:
x1=cos(angle)x-sin(angle)y;
y1=cos(angle)y+sin(angle)x;
(注意使用时要变换坐标原点此处坐标原点为(width / 2, height / 2) )
可以轻易算出其余角小线段的两个端点位置,
private static final float DIVIDE_COUNT = 120; //将圆划分为120等份
private static final double CONVERSION_ANGLE_CONST = Math.PI / 180; //转换角所用的常量
//坐标旋转公式
private float getRotatePointX(float a, float x, float y) {
return (float) ((x - width / 2) * Math.cos(CONVERSION_ANGLE_CONST * a) + (y - height / 2) * Math.sin(CONVERSION_ANGLE_CONST * a)) + width / 2;
}
private float getRotatePointY(float a, float x, float y) {
return (float) ((y - height / 2) * Math.cos(CONVERSION_ANGLE_CONST * a) - (x - width / 2) * Math.sin(CONVERSION_ANGLE_CONST * a)) + height / 2;
}
其余线条绘制方法大致一样,修改修改参数就可以了。
- 绘制文字
绘制文字时要保证的是文字的中点与小线段、圆心在一条直线上
思路就是 先找文字的中点(图中的小红点),也是根据旋转公式得到的,所以他们肯定在一条直线上。
找好点后再绘制文字时将文字偏移(textW/2,textH/2)就将文字放到中心了
文字测量方法:
String test = "120°";
Rect rect = new Rect();
mTextPaint.getTextBounds(test, 0, test.length(), rect);
textW = rect.width();//文字宽
textH = rect.height();//文字高
其余文字大致也是这样找好文字位置再偏移致中点
- 屏幕适配
按照之前的做法文字的大小无法根据控件的大小的改变而改变,
导致当控件设置的大小较小时,文字依然是那么大,不太美观。
所以就用渐变算法去确定文字大小
void initSize() {
edgeTextSize = 38 - (1080 - width) / 30;
edgeTextMargin = 50 - (1080 - width) / 30;
orientationTextSize = 42 - (1080 - width) / 30;
oriTextMargin = 92 - (1080 - width) / 12;
angleTextSize = 60 - (1080 - width) * 4 / 75;
rowPitch = 56 - (1080 - width) / 20;
mainLineLength = 35 - (1080 - width) / 30;
}
渐变公式推导:
△X1/△Y1 = △X2/△Y2 (暂定控件大小的可变范围为 480~1080)
=>>
(1080-480)/(x2-x1)= (1080-x) /(x2-y)
=>>
y= x2 - (1080-x)*(x2-x1)/(600)
文字大小的范围为[18-38]
y= 38 - (1080-x)*(38-18)/(600)
=38 - (1080-x)/30
以此渐变文字大小