Android - 时钟
1、canvas.rotate(degree) 适合在圆弧上画刻度时使用
2、paint.getTextWidths(String,start,end,widths) 计算该画笔下文字宽度
3、canvas.drawTextOnPath(String,path,hOffset,vOffset,paint) 沿着路径描绘文字
4、handler.postDelayed来实现间隔1s重绘功能
5、Paint画笔介绍
* Paint类介绍
*
* Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色,
* 样式等绘制信息,指定了如何绘制文本和图形,画笔对象有很多设置方法,
* 大体上可以分为两类,一类与图形绘制相关,一类与文本绘制相关。
*
* 1.图形绘制
* setARGB(int a,int r,int g,int b);
* 设置绘制的颜色,a代表透明度,r,g,b代表颜色值。
*
* setAlpha(int a);
* 设置绘制图形的透明度。
*
* setColor(int color);
* 设置绘制的颜色,使用颜色值来表示,该颜色值包括透明度和RGB颜色。
*
* setAntiAlias(boolean aa);
* 设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。
*
* setDither(boolean dither);
* 设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
*
* setFilterBitmap(boolean filter);
* 如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示
* 速度,本设置项依赖于dither和xfermode的设置
*
* setMaskFilter(MaskFilter maskfilter);
* 设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等 *
* setColorFilter(ColorFilter colorfilter);
* 设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果
*
* setPathEffect(PathEffect effect);
* 设置绘制路径的效果,如点画线等
*
* setShader(Shader shader);
* 设置图像效果,使用Shader可以绘制出各种渐变效果
*
* setShadowLayer(float radius ,float dx,float dy,int color);
* 在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色
*
* setStyle(Paint.Style style);
* 设置画笔的样式,为FILL,FILL_OR_STROKE,或STROKE
*
* setStrokeCap(Paint.Cap cap);
* 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,如圆形样式
* Cap.ROUND,或方形样式Cap.SQUARE
*
* setSrokeJoin(Paint.Join join);
* 设置绘制时各图形的结合方式,如平滑效果等
*
* setStrokeWidth(float width);
* 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度
*
* setXfermode(Xfermode xfermode);
* 设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果
*
* 2.文本绘制
* setFakeBoldText(boolean fakeBoldText);
* 模拟实现粗体文字,设置在小字体上效果会非常差
*
* setSubpixelText(boolean subpixelText);
* 设置该项为true,将有助于文本在LCD屏幕上的显示效果
*
* setTextAlign(Paint.Align align);
* 设置绘制文字的对齐方向
*
* setTextScaleX(float scaleX);
* 设置绘制文字x轴的缩放比例,可以实现文字的拉伸的效果
*
* setTextSize(float textSize);
* 设置绘制文字的字号大小
*
* setTextSkewX(float skewX);
* 设置斜体文字,skewX为倾斜弧度
*
* setTypeface(Typeface typeface);
* 设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等
*
* setUnderlineText(boolean underlineText);
* 设置带有下划线的文字效果
*
* setStrikeThruText(boolean strikeThruText);
* 设置带有删除线的效果
private Runnable clockRunnable=new Runnable() {
@Override
public void run() {
postInvalidate();
handler.postDelayed(this, 1000);
}
};
public void resume(){
handler=new Handler();
handler.postDelayed(clockRunnable,1000);
}
public void pause(){
handler.removeCallbacks(clockRunnable);
}
5、代码
public class ClockView extends View {
private float radius;
private float numWidths[];
private Paint paint,hourPaint,minutePaint,secondPaint,textPaint,numPaint;
private Path path;
private Handler handler;
private Runnable clockRunnable=new Runnable() {
@Override
public void run() {
postInvalidate();
handler.postDelayed(this, 1000);
}
};
public void resume(){
handler=new Handler();
handler.postDelayed(clockRunnable,1000);
}
public void pause(){
handler.removeCallbacks(clockRunnable);
}
public ClockView(Context context){
super(context);
init(); //初始化
}
private void init(){
//主要画笔
paint=new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(5);
//指针画笔
hourPaint=new Paint();
minutePaint=new Paint();
secondPaint=new Paint();
hourPaint.setColor(Color.BLACK);
hourPaint.setStrokeWidth(8);
minutePaint.setColor(Color.BLACK);
minutePaint.setStrokeWidth(4);
secondPaint.setColor(Color.BLACK);
secondPaint.setStrokeWidth(2);
//表盘文字画笔
textPaint=new Paint();
textPaint.setColor(Color.RED);
textPaint.setTextSize(radius * 0.15f);
textPaint.setStrokeWidth(5);
textPaint.setTextAlign(Paint.Align.CENTER);
path=new Path();
path.addArc(new RectF(-0.7f * radius, -0.7f * radius, 0.7f * radius, 0.7f * radius), 200f, 140f);
//刻度数字画笔
numPaint=new Paint();
numPaint.setTextSize(30);
numPaint.setAntiAlias(true);
numPaint.setStyle(Paint.Style.FILL_AND_STROKE);
numPaint.setStrokeWidth(2);
numPaint.setColor(Color.RED);
//刻度数字文本宽度
numWidths=new float[13];
numPaint.getTextWidths("0123456789", 0, 10, numWidths);
numWidths[10]=numWidths[0]+numWidths[1];
numWidths[11]=numWidths[1]+numWidths[1];
numWidths[12]=numWidths[1]+numWidths[2];
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
radius=Math.min(canvas.getHeight(),canvas.getWidth())/2-100; //半径
canvas.drawColor(Color.WHITE);
canvas.translate(canvas.getWidth() / 2, canvas.getHeight() / 2); //移动画布原点至(x,y)
//外空心圆
canvas.drawCircle(0, 0, radius, paint);
//内实心圆
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.GRAY);
canvas.drawCircle(0, 0, radius * 0.2f, paint);
paint.setColor(Color.BLACK);
canvas.drawCircle(0, 0, radius * 0.1f, paint);
paint.setStyle(Paint.Style.STROKE);
//指针
Calendar time=Calendar.getInstance();
int hour=time.get(Calendar.HOUR);
int minute=time.get(Calendar.MINUTE);
int second=time.get(Calendar.SECOND);
float hourDegree=(hour+minute/60f)*360/12;
float minuteDegree=(minute+second/60f)*360/60;
float secondDegree=time.get(Calendar.SECOND)*360/60;
canvas.rotate(hourDegree);
canvas.drawLine(0, radius * 0.1f, 0, -radius * 0.5f, hourPaint);
canvas.rotate(-hourDegree);
canvas.rotate(minuteDegree);
canvas.drawLine(0, radius * 0.1f, 0, -radius * 0.65f, minutePaint);
canvas.rotate(-minuteDegree);
canvas.rotate(secondDegree);
canvas.drawLine(0, radius * 0.1f, 0, -radius * 0.85f, secondPaint);
canvas.rotate(-secondDegree);
//表盘文字
canvas.drawTextOnPath("2016澳网公开赛-劳力士", path, 0, 0, textPaint);
//刻度
int count=60;
for(int i=0;i<count;i++){
if(i % 5 == 0) {
canvas.drawLine(0f, radius, 0, radius *0.9f, paint);
}else{
canvas.drawLine(0f,radius,0,radius*0.95f,paint);
}
canvas.rotate(360/count);
}
//刻度数字
count=12;
for(int i=0;i<count;i++){
canvas.drawText(String.valueOf(i==0?12:i),-numWidths[i==0?12:i]/2,-radius*1.1f,numPaint);
canvas.rotate(360/count);
}
}
}

浙公网安备 33010602011771号