zoukankan      html  css  js  c++  java
  • 自定义组件-绘制时钟

    1、效果图


    2、Canvas对象详解

    1.translate(x,y):平移,将画布的坐标原点向左右方向移动x,向上下方向移动y.canvas的默认位置是在(0,0).

      例子:画布原点假如落在(1,1),那么translate(10,10)就是在原点(1,1)基础上分别在x轴、y轴移动10,则原点变为(11,11)。
    2.scale(x,y):扩大。x为水平方向的放大倍数,y为竖直方向的放大倍数。
    3.rotate(angel):旋转.angle指旋转的角度,顺时针旋转。
    4.transform():切变。所谓切变,其实就是把图像的顶部或底部推到一边。
    5 save:用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。
    6 restore:用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。save和restore要配对使用(restore可以比save少,但不能多),如果restore调用次数比save多,会引发Error。
    7、drawTextOnPath 在指定的path上面绘制文字。
    3、代码
    package com.example.canvastest.view;
    
    import java.util.Calendar;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Paint.Align;
    import android.graphics.Paint.Style;
    import android.graphics.Path;
    import android.graphics.RectF;
    import android.os.Handler;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.View;
    
    import com.example.canvastest.DensityUtil;
    import com.example.canvastest.R;
    
    /**
     * 绘制时钟
     * 
     * @author libin
     * 
     */
    public class ClockView extends View {
        // 半径
        private float radius = 200;
        private Paint mDownPaint;
        // 宽度
        private float mCirclePaintWidth = 10;
         
        // 上面圆圈的画笔
        private Paint mOutSidePaint;
        // 画文字
        private Paint mTextPaint;
    
        // 文字大小
        private int textFontSize = 16;
        
        private int longLine ;
        private int shortLine;
        private int widthLine ;
        //小圆心的半径
        private int circle;
        
        private int hourDegrees;
        private int minDegrees;
        private int secDegrees;
         
    
        public ClockView(Context context) {
            super(context);
            init();
        }
    
        public ClockView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public ClockView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init() {
            mDownPaint = new Paint();
            mDownPaint.setColor(Color.BLACK);
            mDownPaint.setAntiAlias(true);
            mDownPaint.setStrokeWidth(mCirclePaintWidth);
    
            textFontSize = (int) getResources().getDimension(R.dimen.textSize);
            shortLine = (int) getResources().getDimension(R.dimen.shortLine);
            longLine = (int) getResources().getDimension(R.dimen.longLine);
            widthLine = (int) getResources().getDimension(R.dimen.widthLine);
            radius = (int) getResources().getDimension(R.dimen.circleRadius);
            circle = (int) getResources().getDimension(R.dimen.circle);
            // 上面的画笔
            mOutSidePaint = new Paint();
            mOutSidePaint.setAntiAlias(true);
            mOutSidePaint.setStrokeWidth(mCirclePaintWidth);
            mOutSidePaint.setStyle(Style.STROKE);
            mOutSidePaint.setColor(Color.BLACK);
            // 上面的画笔
            mTextPaint = new Paint();
            mTextPaint.setAntiAlias(true);
            mTextPaint.setColor(Color.BLACK);
            mTextPaint.setStrokeWidth(widthLine);
            mTextPaint.setTextAlign(Align.CENTER);
            
            mTextPaint.setTextSize(textFontSize);
            mDownPaint.setTextSize(textFontSize);
            
            mHandler.sendEmptyMessage(10);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            
            // 平移,将画布的坐标原点向左右方向移动x,向上下方向移动y.canvas的默认位置是在(0,0).
            // 例子:画布原点假如落在(1,1),那么translate(10,10)就是在原点
            // (1,1)基础上分别在x轴、y轴移动10,则原点变为(11,11)。
            canvas.translate(canvas.getWidth() / 2, canvas.getHeight() / 2); // 将位置移动画纸的坐标点:150,150
            // 画圆
            canvas.drawCircle(0, 0, radius, mOutSidePaint);
            canvas.save();
    
            // 绘制路径
            Path path = new Path();
            path.addArc(new RectF(-radius, -radius, radius, radius), -180, 180);
            mDownPaint.setTextAlign(Align.CENTER);
    
            int pathy = DensityUtil.dip2px(getContext(), -5);
            // 让文字显示到中间
            canvas.drawTextOnPath("canvas绘制钟表", path, 0, pathy, mDownPaint);
            canvas.restore();
    
            //绘制刻度
            canvas.save();
            canvas.rotate(210);
            float y = radius;
            int count = 60; // 总刻度数
            for (int i = 0; i < count; i++) {
                if (i % 5 == 0) {
                    canvas.drawLine(0f, y-longLine+2, 0, y+mCirclePaintWidth/2 , mTextPaint);
                    canvas.drawText(String.valueOf(i / 5 + 1), 0, y -mCirclePaintWidth/2-longLine, mTextPaint);
    
                } else {
                    canvas.drawLine(0f, y  - shortLine , 0f,y-mCirclePaintWidth/2, mTextPaint);
                }
                canvas.rotate(360 / count, 0f, 0f); // 旋转画纸
            }
            canvas.restore();
         
            
            //绘制秒针
            canvas.save();
            canvas.rotate(secDegrees);
            Paint hourPaint = new Paint(mDownPaint);
            hourPaint.setColor(Color.BLACK);
            hourPaint.setStrokeWidth(circle);
             
            canvas.drawLine(0, -longLine, 0, radius*2/3, hourPaint);
            canvas.restore();
            
            //绘制分针
            canvas.save();
            canvas.rotate(minDegrees);
            canvas.drawLine(0, -longLine, 0, radius*1/2, hourPaint);
            canvas.restore();
        
            //绘制时针
            canvas.save();
            canvas.rotate(hourDegrees);
            canvas.drawLine(0, -longLine, 0, radius*1/3, hourPaint);
            canvas.restore();
    
            //绘制中心黑点
            Paint tmpPaint = new Paint(mDownPaint);
            tmpPaint.setColor(Color.BLACK);
            canvas.drawCircle(0, 0, circle*2, tmpPaint);
             
             
            //绘制中心红点
            tmpPaint.setColor(Color.RED);
            canvas.drawCircle(0, 0, circle*4/3, tmpPaint);
            super.onDraw(canvas);
        }
     
        /**
         * 获取角度
         */
        private void calculate(){
            Calendar calendar = Calendar.getInstance();
            int hour = calendar.get(Calendar.HOUR);
            if (hour>12) {
                hour = hour-12;
            }
            hourDegrees = hour*30-180;
            
            int min = calendar.get(Calendar.MINUTE);
            minDegrees = min * 6-180;
            
            int sec = calendar.get(Calendar.SECOND);
            secDegrees = sec * 6-180;
            Log.i("tag", " "+ hour+" "+min+" "+sec);
        }
        
        /**
         * 定时器
         */
        private Handler mHandler = new Handler(){
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                case 10:
                    calculate();
                    invalidate();
                    this.sendEmptyMessageDelayed(10, 1000);
                    break;
                default:
                    break;
                }
            };
        };
    }
    4、常量数据
     <dimen name="textSize">14sp</dimen>
        <dimen name="circleRadius">100dip</dimen>
        <dimen name="shortLine">9dip</dimen>
        <dimen name="longLine">15dip</dimen>
        <dimen name="widthLine">5dip</dimen>
        <dimen name="circle">3dip</dimen>



  • 相关阅读:
    Spring messageSource
    Spring MVC集成Tiles使用方法
    Jquery发送ajax请求以及datatype参数为text/JSON方式
    怎样使用jsp实现header和footer与网页内容的分离
    jsp:include怎么设置才能正确显示包含的页面呢
    JSP中两种include的区别
    让html文件也具体include包含的功能
    DWZ中uploadify多文件上传
    DWZ+Uploadify +JSON 多文件上传
    dwz+jquery+fileupload+springmvc实现文件上传 及图片预览
  • 原文地址:https://www.cnblogs.com/lbangel/p/4335850.html
Copyright © 2011-2022 走看看