android 实时时钟,android自定义钟表

android自定义钟表

首先看看效果图先

57356af5a677

time.gif

然后看看自定义的属性

在xml界面的编写

自定义各参数的初始化

public ClockView(Context context) {

this(context,null);

}

public ClockView(Context context, AttributeSet attrs) {

this(context, attrs,0);

}

public ClockView(Context context, AttributeSet attrs, int defStyleAttr){

super(context, attrs, defStyleAttr);

display((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); screemWidth=display.getWidth(); screemHeight=display.getHeight();

float density=getResources().getDisplayMetrics().density; marginLongPoint=(int)density*8;

maginShortPoint=(int)density*16;

maginRadius=(int)density*10;

maginText=(int)density*10;

hourMargin=(int)density*75;

minuteMargin=(int)density*40;

TypedArray typedArray=context.getTheme().obtainStyledAttributes(attrs,R.styleable.ClockView,defStyleAttr,0);

int numCount=typedArray.getIndexCount();

for(int i=0;i

int attr=typedArray.getIndex(i);

switch(attr){

case R.styleable.ClockView_numSize: numSize=typedArray.getDimensionPixelSize(attr,(int)TypedValue .applyDimension(TypedValue.COMPLEX_UNIT_SP,15,getResources().getDisplayMetrics()));

break;

case R.styleable.ClockView_color: color=typedArray.getColor(attr,Color.BLACK);

break;

case R.styleable.ClockView_inCircle:

inCircle=typedArray.getInt(attr,15);

break;

case R.styleable.ClockView_outCircle:

outCircle=typedArray.getInt(attr,25);

break;

}

}

typedArray.recycle();

initCanvas();

}

接下来就是设定这个自定义View的大小,在没有大小自适应的时候,view的高度我这位整个手机屏幕高度的三分之一,宽度为整个屏幕的宽度

if(widthModel==MeasureSpec.EXACTLY){ width=widthSize;

}else{

width=screemWidth;

} if(heightModel==MeasureSpec.EXACTLY){

height=heightSize;

}else{

height=screemHeight/3;

}

在onDraw()方法里我们就可以开始画图了

@Override

protected void onDraw(Canvas canvas) {

//得到圆的半径 if(getWidth()>getHeight()){

radius=getHeight()/2-maginRadius;

}else{

radius=getWidth()/2-maginRadius;

}

//获得View一半的宽度和高度

halfWidth=getWidth()/2;

halfHeight=getHeight()/2;

//保存状态

canvas.save();

//画大圆

canvas.drawCircle(halfWidth,halfHeight,radius,paint);

//画中间大圆

canvas.drawCircle(halfWidth,halfHeight,outCircle,inCirclePaint);

//画中间小圆

canvas.drawCircle(halfWidth,halfHeight,inCircle,outCirclePaint);

//画60个刻度和时钟数字

drawClockScale(canvas);

//绘制时间指针

refreshTime(canvas);

//返回状态

canvas.restore();

//每隔一秒刷新 postInvalidateDelayed(1000);

}

首先我们画的是外部的圆圈和正中间的半透明的大圆和小圆 ,即得到整个view的中心点也就是一半的宽(halfWidth)和高(halfHeight)画半径为radius的圆

代码如下:

//画大圆

canvas.drawCircle(halfWidth,halfHeight,radius,paint);

//画中间大圆

canvas.drawCircle(halfWidth,halfHeight,outCircle,inCirclePaint);

//画中间小圆

canvas.drawCircle(halfWidth,halfHeight,inCircle,outCirclePaint);

57356af5a677

GIF1.gif

接着就是要画60个刻度和时钟数字这是整个自定义的难点和重点,不说废话先贴代码:

画60个刻度和时钟数字

//画60个刻度

public void drawClockScale(Canvas canvas){ canvas.translate(halfWidth,halfHeight); canvas.save();

//长指针的长

LongCalibration=radius/marginLongPoint;

//短指针的长

ShortCalibration=radius/maginShortPoint;

for(int i=0;i

if(i%5==0){

//绘画文字

canvas.save();

Rect rect=new Rect();

int number=i==0?12:(i/5);

textPaint.getTextBounds((number+""),0,(number+"").length(),rect); canvas.translate(0,-radius+LongCalibration+((rect.bottom-rect.top)/2)+maginText);

canvas.rotate(-6*i);

canvas.drawText(number+"",0,(rect.bottom-rect.top)/2,textPaint); canvas.restore();

//画线

canvas.drawLine(0,-radius+LongCalibration,0,-radius,paint);

}else{

canvas.drawLine(0,-radius+ShortCalibration,0,-radius,paint);

}

canvas.rotate(6);

}

canvas.restore();

}

pointNum=60即60个指针刻度,我们先把canvas的坐标原点移动到整个View的中心即canvas.translate(halfWidth,halfHeight);接着这个圆是360度我们有60个刻度即每个刻度的旋转角度为6度,所以我们每一次循环都要把canvas旋转6度即canvas.rotate(6)。理解这个之后我们每次循环通过canvas.drawline画出刻度,其中LongCalibration是长刻度的长,而ShortCalibration就是短刻度的长,

canvas.drawLine(0,-radius+LongCalibration,0,-radius,paint);

57356af5a677

git2.PNG

即旋转画出X轴Y轴为(0,-radius+LongCalibration)和(0,-radius)这两点的直线。接着就是画文字了,首先Rect计算出显示的数字的大小,再把canvas的原点移动半径减去刻度的长度和数字一半大小,自定义的间隙之后的距离,此时原点的位置就是需要画出的数字的位置,canvas在旋转-6*i的距离才能使字体竖直,效果如下:

57356af5a677

time2.PNG

绘制时间指针

//获取时间指针对应的角度

public void refreshTime(Canvas canvas){

//获取获取当前的时间

Calendar mCalendar=Calendar.getInstance();

int tempHour=mCalendar.get(Calendar.HOUR);

int tempMinute=mCalendar.get(Calendar.MINUTE);

int tempSecond=mCalendar.get(Calendar.SECOND);

int hourRotate=new Float(360*((float)tempHour/12)).intValue();

//计算出份指针的旋转的角度

int minuteRotate=new Float(360*((float)tempMinute/60)).intValue(); //计算出时指针旋转的角度,注(时的角度是当前小时的角度再加分钟所引起小时偏转的角度)

hourRotate+=new Float(30*((float)minuteRotate/360)).intValue();

//计算出秒指针旋转的角度

int secondRotate=new Float(360*((float)tempSecond/60)).intValue(); drawCircleLine(canvas,hourRotate,minuteRotate,secondRotate);

}

//时间指针

public void drawCircleLine(Canvas canvas,int hour,int minute,int second){

marginLong=radius-LongCalibration-minuteMargin; marginShort=radius-LongCalibration-hourMargin; canvas.rotate(180);

//画小时指针

RectF hourRectF=new RectF(-pointRadio,-pointRadio,pointRadio,marginShort); canvas.save(); canvas.rotate(hour); canvas.drawRoundRect(hourRectF,circular,circular,outCirclePaint); canvas.restore();

//画分钟指针

RectF minuteRectF=new RectF(-pointRadio,-pointRadio,pointRadio,marginLong); canvas.save(); canvas.rotate(minute); canvas.drawRoundRect(minuteRectF,circular,circular,outCirclePaint); canvas.restore();

//画秒指针 canvas.save(); canvas.rotate(second); canvas.drawLine(0,0,0,radius-10,secondPaint);

canvas.restore();

}

这里需要说的是

RectF hourRectF=new RectF(-pointRadio,-pointRadio,pointRadio,marginShort);

用来确定指针的位置,pointRadio代表的是这个矩形的半径,而 canvas.rotate(180);旋转180保证按我们正常的思路一样指针向上,设RectF的左上角为(-pointRadio,-pointRadio)是为了保持在中心点(注:此时canvas的原点是view的中心),剩下就是画指针了。效果图如下:

57356af5a677

time3.PNG

不用这是静态图,最后调用postInvalidateDelayed(1000);保证每个一秒就调用onDraw()方法来重绘View来实现view的每个一秒的动态变化,这样就完成效果图的功能。

最后源码链接

如果对你有帮助就请给我给星星或喜欢吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值