packagecom.example.myview;
importjava.text.DecimalFormat;
importandroid.content.Context;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.Paint;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.util.AttributeSet;
importandroid.util.Log;
importandroid.view.MotionEvent;
importandroid.view.View;
public classClockView extendsView {
//用于发送消息修改UIprivateHandler handler;
privatePaint circlePaint, dialPaint, numberPaint;
//View的宽高private floatmWidth;
private floatmHeight;
//圆的半径private floatcircleRadius;
//圆的X,Y坐标private floatcircleX;
private floatcircleY;
//小针doublesecond= 87.50;
//private int minute;//小时private doublehour;
private floatsecondX;
private floatsecondY;
private booleanisFirst= true;
//内圆的X,Y坐标private floatcircleInX;
private floatcircleInY;
//被点击点x的坐标到圆心x轴的坐标private floatx;
//被点击点y坐标到圆心y轴的坐标private floaty;
publicClockView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
}
private voidinitPaint() {
Log.i("xyz","initPaint....................");
//TODO Auto-generated method stub//刻盘圆,小时刻度,时针和分针的画笔circlePaint= newPaint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setColor(Color.BLACK);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeWidth(10);
//分钟钟刻度的画笔dialPaint= newPaint(Paint.ANTI_ALIAS_FLAG);
dialPaint.setColor(Color.BLACK);
dialPaint.setStrokeWidth(5);
//数字的画笔numberPaint= newPaint(Paint.ANTI_ALIAS_FLAG);
numberPaint.setColor(Color.BLACK);
numberPaint.setStrokeWidth(5);
numberPaint.setTextSize(30);
}
@Overrideprotected voidonMeasure(intwidthMeasureSpec, intheightMeasureSpec) {
//TODO Auto-generated method stubLog.i("xyz","onMeasure.......................");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//getMesureWidth()获取到是这个View原始的大小也就是View在xml中确定的大小//通过getWidth()获得到的是View最后显示出来的大小//这两个方法最后得到的大小可能一样也可能不一样mWidth= getMeasuredWidth();
mHeight= getMeasuredHeight();
//判断拿到的原始View的大小,使用小的作为半径的参考,这样才不会出现圆不见了一部分if(mWidth< mHeight) {
//圆的半径为view的宽度的一半再减9,防止贴边circleRadius= mWidth/ 2- 9;
circleX= mWidth/ 2;
circleY= mHeight/ 2;
circleInX= circleX- 20;
circleInY= circleY- 20;
} else{
circleRadius= mHeight/ 2- 9;
circleX= mWidth/ 2;
circleY= mHeight/ 2;
circleInX= circleX- 20;
circleInY= circleY- 20;
}
}
@Overrideprotected voidonDraw(Canvas canvas) {
super.onDraw(canvas);
//画出圆的圆心,也就是外圆的圆心drawCirclePoint(canvas);
//画出外层的圆drawCircle(canvas);
//画出第二层的圆drawLittleCircle(canvas);
//画刻度,在这里了,没有调用该方法,你可以去掉看看效果//drawDial(canvas);//初始化环上小圆点drawPointer(canvas);
//画环上小圆点drawInPointer(canvas);
}
private voiddrawInPointer(Canvas canvas) {
circlePaint.setColor(Color.BLUE);
canvas.drawCircle((float) (secondX/ 0.85), (float) (secondY/ 0.85), (float) 5, circlePaint);
circlePaint.setColor(Color.BLACK);
}
@Overridepublic booleanonTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
x= (event.getX() - circleX);
y= (event.getY() - circleY);
changeView(x, y);
}
if(event.getAction() == MotionEvent.ACTION_MOVE) {
x= (event.getX() - circleX);
y= (event.getY() - circleY);
changeView(x, y);
}
if(event.getAction() == MotionEvent.ACTION_UP) {
x= (event.getX() - circleX);
y= (event.getY() - circleY);
changeView(x, y);
}
return true;
}
//当private voidchangeView(floatx, floaty) {
floatr;
r = (float) Math.sqrt(x * x + y * y);
//改变圆环上圆的位置,不懂得同学可以画一个图算算secondX= x / r * circleRadius* 0.8f;
secondY= y / r * circleRadius* 0.8f;
changeViewFirst(x + circleX, y + circleY);
invalidate();
}
private floatm_angle;
private voidchangeViewFirst(floatx, floaty) {
//坐标在第一象限if(x > circleX&& y < circleY) {
floatangle = (float) (Math.atan2(x - circleX, circleY- y) / 3.14* 180);
second= angle / 360* 20.5+ 87.50;
Log.i("xyz", "1:"+ second);
upTextView();
invalidate();
}
//坐标在第二象限if(x > circleX&& y > circleY) {
floatangle = (float) (90.0+ Math.atan2(y - circleY, x - circleX) / 3.14* 180);
second= angle / 360* 20.5+ 87.50;
Log.i("xyz", "2:"+ second);
upTextView();
invalidate();
}
//坐标在第三象限if(x < circleX&& y > circleY) {
floatangle = (float) (180.0+ Math.atan2(circleX- x, y - circleY) / 3.14* 180);
second= angle / 360* 20.5+ 87.50;
Log.i("xyz", "3:"+ second);
upTextView();
invalidate();
}
//坐标在第四象限if(x < circleX&& y < circleY) {
floatangle = (float) (270.0+ Math.atan2(circleY- y, circleX- x) / 3.14* 180);
second= angle / 360* 20.5+ 87.50;
Log.i("xyz", "4:"+ second);
upTextView();
invalidate();
}
}
//初始化移动小圆的坐标,其实这里可以做优化但是我没做懒得做了,只会跑一次private voiddrawPointer(Canvas canvas) {
canvas.translate(circleX, circleY);
if(isFirst) {
secondX= (float) Math.cos(Math.toRadians((second- (87.50)) * (360.00/ 20.50) + 270)) * circleRadius* 0.8f;
secondY= (float) Math.sin(Math.toRadians((second- (87.50)) * (360.00/ 20.50) + 270)) * circleRadius* 0.8f;
isFirst= false;
}
//canvas.drawLine(0,0,secondX,secondY,dialPaint);}
//画刻度,private voiddrawDial(Canvas canvas) {
//长刻度画笔Point startPoint = newPoint(circleX, circleY- circleRadius);
Point endPoint = newPoint(circleX, circleY- circleRadius+ 40);
//短刻度画笔Point startPoint2 = newPoint(circleX, circleY- circleRadius);
Point endPoint2 = newPoint(circleX, circleY- circleRadius+ 10);
//开始画刻度和数字,总共60个刻度,6个mHZ刻度,被10整除画一个mHZ刻度,被其余的为小刻度String clockNumber;
doublemHz = 87.50;
for(doublei = 0; i < 60; i++) {
if(i % 15== 0) {
if(i == 0) {
clockNumber = "87.50";
} else{
clockNumber = String.format("%.2f", (20.50* (i / 60) + 87.50));
}
//时针刻度canvas.drawLine(startPoint.getX(), startPoint.getY(), endPoint.getX(), endPoint.getY(), circlePaint);
//画数字,需在时针刻度末端加30使canvas.drawText(clockNumber, circleX- numberPaint.measureText(clockNumber) / 2, endPoint.getY() + 30, numberPaint);
} else{
//画小针刻度canvas.drawLine(startPoint2.getX(), startPoint2.getY(), endPoint2.getX(), endPoint2.getY(), circlePaint);
}
//画布旋转6度canvas.rotate(360/ 60, circleX, circleY);
}
}
//画出最大的圆private voiddrawCircle(Canvas canvas) {
canvas.drawCircle(circleX, circleY, circleRadius, circlePaint);
}
//画出内圆private voiddrawLittleCircle(Canvas canvas) {
canvas.drawCircle(circleX, circleY, circleRadius- 20, circlePaint);
}
//花圆点private voiddrawCirclePoint(Canvas canvas) {
circlePaint.setColor(Color.WHITE);
canvas.drawCircle(circleX, circleY, 5, circlePaint);
circlePaint.setColor(Color.BLACK);
}
//Acvitity跑起来的时候调用public voidstartClock(Handler handler) {
invalidate();
this.handler= handler;
upTextView();
}
//修改UI界面voidupTextView() {
DecimalFormat df = newDecimalFormat("######0.00");
Message message = Message.obtain();
message.obj= df.format(second);
handler.sendMessage(message);
}
}