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);
        }
    }
}

  

  

  

 

posted @ 2016-02-04 11:17  chenyizh  阅读(128)  评论(0)    收藏  举报