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画笔介绍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | * 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); * 设置带有删除线的效果 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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、代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | 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); } } } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步