效果
思路
- 先绘制刻度和文字,通过旋转画布来操作
//移动画布到屏幕正中间
canvas.translate(getMeasuredWidth() / 2, getMeasuredHeight() / 2);
//当前数字
int currentP = 0;
//绘制的数字
String text = "";
int len;
for (int i = 0; i < 360 / fixAngle; i++) {
if (i % 5 == 0) {
if (currentP == 0) {
text = "12";
} else {
text = currentP + "";
}
currentP++;
mArcPaint.setColor(Color.BLUE);
mArcPaint.setTextSize(40);
mArcPaint.getTextBounds(text, 0, text.length(), mTextBound);
canvas.drawText(text, 0, text.length(), -mTextBound.width() / 2, -(radius + b_len + 20), mArcPaint);
mArcPaint.setColor(Color.RED);
len = b_len;
} else {
mArcPaint.setColor(Color.GREEN);
len = s_len;
}
canvas.drawLine(0, -radius, 0, -(radius + len), mArcPaint);
//旋转画布
canvas.rotate(fixAngle);
}
- 绘制指针
/**
* 画秒针
* @param canvas
*/
private void drawS(Canvas canvas) {
double angle = (s * fixAngle - 90)*Math.PI/180;
int mSecondLen = 280;
int startX = -(int) (len * Math.cos(angle));
int startY = -(int) (len * Math.sin(angle));
int endX = (int) ((mSecondLen - len) * Math.cos(angle));
int endY = (int) ((mSecondLen - len) * Math.sin(angle));
canvas.drawLine(startX, startY, endX, endY, sPaint);
}
/**
* 画分针
* @param canvas
*/
private void drawM(Canvas canvas) {
double angle = (m * 6 - 90)*Math.PI/180;
int mMinLen = 250;
int startX = -(int) (len * Math.cos(angle));
int startY = -(int) (len * Math.sin(angle));
int endX = (int) ((mMinLen - len) * Math.cos(angle));
int endY = (int) ((mMinLen - len) * Math.sin(angle));
canvas.drawLine(startX, startY, endX, endY, minPaint);
}
/**
* 画时针
* @param canvas
*/
private void drawH(Canvas canvas) {
double angle = (h * 6 * 5 - 90)*Math.PI/180+((m *1.0f/60 *30)*Math.PI/180);
int mHourLen = 230;
int startX = -(int) (len * Math.cos(angle));
int startY = -(int) (len * Math.sin(angle));
int endX = (int) ((mHourLen - len) * Math.cos(angle));
int endY = (int) ((mHourLen - len) * Math.sin(angle));
canvas.drawLine(startX, startY, endX, endY, hPaint);
}
- 绘制中心原点
private void drawPoint(Canvas canvas) {
mArcPaint.setColor(Color.WHITE);
canvas.drawCircle(0, 0, 10, mArcPaint);
}
遇到的问题
怎么实时刷新时间 让指针转起来?
方案一
- 继承自View
- 开线程,添加一个循环,然后通过
handler
去调用invalidate()
结果:打开界面几秒后 app 直接崩溃
方案二
- 继承自View
- 在
onDraw()
内加入以下代码
@Override
protected void onDraw(Canvas canvas) {
.....
postInvalidateDelayed(1000);
invalidate();
}
结果:其实就是一个死循环,效果是出来了,但是内存抖动特别厉害,频繁的触发GC,
去掉代码 invalidate(); 后可以正常出效果,内存也正常。
方案三
- 继承自 SurfaceView
- 缓存一个图层
private void drawUI() {
try {
canvas = mSurfaceHolder.lockCanvas();
//缓存一个图层
if (bitmapCache == null) {
bitmapCache = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_4444);
}
canvas1 = new Canvas(bitmapCache);
canvas1.drawColor(Color.BLACK);
drawCanvas(canvas1);
canvas.drawBitmap(bitmapCache, 0, 0, mPaint);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
mSurfaceHolder.unlockCanvasAndPost(canvas);
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果:实现效果,内存也还比较稳定