本文实例为大家分享了Android自定义View实现时钟效果的具体代码,供大家参考,具体内容如下
自定义时钟
初学自定义View,先画一个不太成熟的时钟(甚至只有秒针)
时钟效果
@SuppressLint("DrawAllocation")
public class ClockView extends View {
private final Context mContext;
private Canvas mCanvas;// 画布
private Paint clockPaint;// 表盘画笔
private Paint textPaint;// 文字画笔
private Paint secondPaint;// 秒针画笔
private int x,y;// 表中心坐标
private Thread refreshThread;
private boolean isStop = false;
// 用于获取当前秒数
private Date currentDate;
private SimpleDateFormat sp = new SimpleDateFormat("ss");
@SuppressLint("HandlerLeak")
private final Handler mHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(msg.what == 0){
invalidate();//每隔一秒刷新一次
}
}
};
public ClockView(Context context) {
this(context,null);
}
public ClockView(Context context, @Nullable AttributeSet attrs) {
this(context,null,0);
}
public ClockView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
this(context,null,0,0);
}
public ClockView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
this.mContext = context;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMeasure;
// 设置宽高一致
if(widthMeasureSpec > heightMeasureSpec){
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
widthMeasure = getMeasuredHeight();
}else{
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
widthMeasure = getMeasuredWidth();
}
initPaint(widthMeasure);
}
private void initPaint(int width){
// 表盘画笔
clockPaint = new Paint();
clockPaint.setColor(mContext.getColor(R.color.black));// 颜色
clockPaint.setAntiAlias(true);// 抗锯齿
clockPaint.setStyle(Paint.Style.STROKE);// 样式
clockPaint.setStrokeWidth(width/80f);// 宽度
//字体画笔
textPaint = new Paint();
textPaint.setColor(mContext.getColor(R.color.black));
textPaint.setAntiAlias(true);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setTextSize(width/16f);
textPaint.setTextAlign(Paint.Align.CENTER);
// 秒针画笔
secondPaint = new Paint();
secondPaint.setColor(mContext.getColor(R.color.red));
secondPaint.setAntiAlias(true);
secondPaint.setStyle(Paint.Style.FILL);
secondPaint.setStrokeWidth(5f);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mCanvas = canvas;
// 获取画布中心坐标
x = getWidth() / 2;
y = getHeight() / 2;
// 绘制表盘
mCanvas.drawCircle(x, y,getWidth()/40f, clockPaint);// 表盘中心
mCanvas.drawCircle(x, y, x -getWidth()/40f, clockPaint);// 表盘边框
// 绘制刻度
for(int i = 1;i <= 60;i++){
mCanvas.rotate(6, x, y);
if(i%5 == 0){
// 绘制大刻度
mCanvas.drawLine(x, getWidth()*3/80f, x, getWidth()*5/80f, clockPaint);
}else{
// 绘制小刻度
mCanvas.drawLine(x, getWidth()*3/80f, x, getWidth()/20f, clockPaint);
}
}
// 绘制 1-12小时 字体
for(int i = 1;i <= 60;i++){
if(i%5 == 0){
float x1 = (float) Math.sin(Math.toRadians(6 * i)) * (y * 3 / 4f) + x;
float y1 = y - (float) Math.cos(Math.toRadians(6 * i)) * (y * 3 / 4f) + getWidth()/40f;
mCanvas.drawText(String.valueOf(i/5), x1, y1, textPaint);
}
}
// 绘制秒针
currentDate = new Date(System.currentTimeMillis());
int ss = Integer.parseInt(sp.format(currentDate));// 获取当前秒数
// 根据当前秒数 计算出秒针的 start 及 end 坐标
float sin = (float) Math.sin(Math.toRadians(6 * ss));
float cos = (float) Math.cos(Math.toRadians(6 * ss));
float x0 = x - sin * (y / 10f);
float y0 = y + cos * (y / 10f);
float x1 = x + sin * (y * 13 / 20f);
float y1 = y - cos * (y * 13 / 20f);
mCanvas.drawLine(x0, y0, x1, y1, secondPaint);
mCanvas.drawCircle(x, y,getWidth()/80f, secondPaint);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
refreshThread = new Thread(){
@Override
public void run() {
super.run();
while (!isStop){
SystemClock.sleep(1000);
mHandler.sendEmptyMessage(0);
}
}
};
refreshThread.start();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mHandler.removeCallbacksAndMessages(null);
isStop = true;
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。