美文网首页
自定义时钟效果

自定义时钟效果

作者: 玖玖君 | 来源:发表于2019-10-31 09:48 被阅读0次

自定义的ClockView类

/**
 * 自定义View系列-时钟Clock
 */
public class ClockView extends View {

    private static final String TAG = ClockView.class.getSimpleName();

    /**
     * 上下文
     */
    private Context mContext;
    /**
     * 背景绘制画笔
     */
    private Paint mPaintBg;
    /**
     * 时钟元素画笔
     */
    private Paint mPaint;
    /**
     * 绘制指针的画笔
     */
    private Paint mPaintLine;
    /**
     * 绘制数字的画笔
     */
    private Paint mPaintText;
    /**
     * 0-11
     */
    private int mCurrentHour = 0;
    /**
     * 0-59
     */
    private int mCurrentMinute = 0;
    /**
     * 0-59
     */
    private int mCurrentSecond = 0;

    /**
     * 指针长度-时针
     */
    private float mDistanceHour;
    /**
     * 指针长度-分针
     */
    private float mDistanceMinute;
    /**
     * 指针长度-秒针
     */
    private float mDistanceSecond;
    /**
     * 偏移量
     */
    private float offset;
    /**
     * 时间间隔
     */
    private int TIME = 1000;//默认每隔10ms重绘一次
    /**
     * Handler
     */
    Handler handler = new Handler();
    /**
     * Runnable
     */
    Runnable runnable = new Runnable() {

        @Override
        public void run() {
            try {
                handler.postDelayed(this, TIME);
                switch (mTypeModel) {
                    case CURRENT_MODEL:
                        getCurrentTime();
                        break;
                    case DEFAULT_MODEL:
                        getDefaultTime();
                        break;
                }
                invalidate();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };

    public ClockView(Context context) {
        this(context, null);
    }

    public ClockView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ClockView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        initView();
        offset = dip2px(mContext, 10);
    }

    /**
     * 初始化
     */
    private void initView() {
        mPaintBg = new Paint();
        mPaintBg.setAntiAlias(true);
        mPaintBg.setColor(Color.BLACK);
        mPaintBg.setStrokeWidth(dip2px(mContext, 2));
        mPaintBg.setStyle(Paint.Style.STROKE);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.FILL);

        mPaintLine = new Paint();
        mPaintLine.setAntiAlias(true);
        mPaintLine.setStyle(Paint.Style.FILL);
        mPaintLine.setStrokeWidth(dip2px(mContext, 2));

        mPaintText = new Paint();
        mPaintText.setAntiAlias(true);
        mPaintText.setColor(Color.BLACK);
        mPaintText.setStyle(Paint.Style.STROKE);
        mPaintText.setTextSize(30);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mDistanceHour = w / 5 - dip2px(mContext, 7);
        mDistanceMinute = mDistanceHour + dip2px(mContext, 18);
        mDistanceSecond = mDistanceHour + dip2px(mContext, 45);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(getWidth() / 2, getHeight() / 2);
        drawClock(canvas);
        drawHour(canvas);
        drawMinute(canvas);
        drawSecond(canvas);

        /**
         * 绘制中心点
         */
        canvas.drawCircle(0, 0, 20, mPaint);
    }

    /**
     * 绘制时钟基本的元素
     *
     * @param canvas
     */
    private void drawClock(Canvas canvas) {
        //绘制圆圈背景
        canvas.drawCircle(0, 0, (getWidth() - dip2px(mContext, 2)) / 2, mPaintBg);
        //绘制文字和小圆点
        for (int i = 0; i < 12; i++) {

            float r = getWidth() / 2 - offset;
            float deg = i * 30 + 30;
            float x = (float) (r * Math.sin(Math.PI * deg / 180));
            float y = (float) (r * Math.cos(Math.PI * deg / 180));

            canvas.drawCircle(x, -y, dip2px(mContext, 3), mPaint);

            //绘制进度数字
            String text = (i + 1) + "";
            //获取文字宽度
            float textWidth = mPaintText.measureText(text, 0, text.length());
            float dx = x - x / 10 - textWidth / 2;
            Paint.FontMetricsInt fontMetricsInt = mPaintText.getFontMetricsInt();
            float dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
            float baseLine = -(y - y / 10) + dy;
            canvas.drawText(text, dx, baseLine, mPaintText);
        }
    }


    /**
     * 绘制时针
     *
     * @param canvas
     */
    private void drawHour(Canvas canvas) {
        mPaintLine.setColor(Color.BLACK);
        /**
         * 找到时间和弧度的关系,先计算出总的时间加在一起是多少个小时,
         * 然后根据小时数计算出在时钟上需要绘制的角度是多少,再求出坐标进行绘制
         */
        float hour = (float) mCurrentHour + (float) mCurrentMinute / 60 + (float) mCurrentSecond / 3600;
        float deg1 = hour * 30;
        Log.i(TAG, "度数deg1:" + hour);
        float x1 = (float) (mDistanceHour * Math.sin(Math.PI * deg1 / 180));
        float y1 = (float) (mDistanceHour * Math.cos(Math.PI * deg1 / 180));
        //canvas.drawCircle(x1, -y1, 10, mPaintLine);
        canvas.drawLine(0, 0, x1, -y1, mPaintLine);
    }


    /**
     * 绘制分针
     *
     * @param canvas
     */
    private void drawMinute(Canvas canvas) {
        mPaintLine.setColor(Color.BLACK);
        /**
         * 找到时间和弧度的关系
         */
        float minute = (float) mCurrentMinute + (float) mCurrentSecond / 60;
        float deg1 = minute * 6;
        Log.i(TAG, "===度数minute:" + minute + "===度数deg1:" + deg1);
        float x1 = (float) (mDistanceMinute * Math.sin(Math.PI * deg1 / 180));
        float y1 = (float) (mDistanceMinute * Math.cos(Math.PI * deg1 / 180));
        //canvas.drawCircle(x1, -y1, 10, mPaintLine);
        canvas.drawLine(0, 0, x1, -y1, mPaintLine);
    }

    /**
     * 绘制秒针
     *
     * @param canvas
     */
    private void drawSecond(Canvas canvas) {
        mPaintLine.setColor(Color.RED);
        /**
         * 找到时间和弧度的关系
         */
        float deg1 = mCurrentSecond * 6;
        Log.i(TAG, "===度数deg1:" + deg1);
        float x1 = (float) (mDistanceSecond * Math.sin(Math.PI * deg1 / 180));
        float y1 = (float) (mDistanceSecond * Math.cos(Math.PI * deg1 / 180));
        //canvas.drawCircle(x1, -y1, 10, mPaintLine);
        canvas.drawLine(0, 0, x1, -y1, mPaintLine);
    }


    /**
     * 开始
     */
    public void start() {
        stop();
        handler.postDelayed(runnable, TIME); //每隔TIMEms执行
    }

    public void stop() {
        try {
            handler.removeCallbacks(runnable);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取当前时间
     */
    private void getCurrentTime() {
        Calendar now = Calendar.getInstance();
        mCurrentHour = now.get(Calendar.HOUR_OF_DAY);
        mCurrentMinute = now.get(Calendar.MINUTE);
        mCurrentSecond = now.get(Calendar.SECOND);
    }

    private long timeSeconds = 32353450;

    private void getDefaultTime() {
        timeSeconds++;
        mCurrentHour = (int) (timeSeconds / 60 / 60 % 60);
        mCurrentMinute = (int) (timeSeconds / 60 % 60);
        mCurrentSecond = (int) (timeSeconds % 60);
    }

    private TYPE_MODEL mTypeModel = TYPE_MODEL.DEFAULT_MODEL;

    public enum TYPE_MODEL {
        CURRENT_MODEL, DEFAULT_MODEL;
    }

    public void startSpeed() {
        mTypeModel = TYPE_MODEL.DEFAULT_MODEL;
        TIME = 1;
    }

    public void defaultModel() {
        TIME = 1000;
        mTypeModel = TYPE_MODEL.CURRENT_MODEL;
    }


    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

}

调用
  mClock = (ClockView) findViewById(R.id.clock);
        //启动时钟
        mClock.start();

 /**
     * 加快版
     *
     * @param view
     */
    public void clickSpeed(View view) {
        mClock.startSpeed();
    }

    /**
     * 当前时间
     *
     * @param view
     */
    public void clickDefault(View view) {
        mClock.defaultModel();
    }


  //获取当前时间,时分秒
        Calendar now = Calendar.getInstance();

        mCurrentHour = now.get(Calendar.HOUR_OF_DAY);

        mCurrentMinute = now.get(Calendar.MINUTE);

        mCurrentSecond = now.get(Calendar.SECOND);

相关文章

  • 自定义时钟效果

    自定义的ClockView类 调用

  • 时钟效果

    demo在这里 layer 动画时钟,计算了分钟和小时的具体角度,运行看起来不那么生硬

  • android自定义时钟

    关于android自定义时钟网上已经有很多了,百度一下“android自定义时钟”能看到很多大佬们自定义的时钟...

  • Android 自定义View之: 时钟控件

    学习自定义View,遂动手写了一个时钟控件,欢迎批评指正。 首先上效果图: GitHub地址 代码下载 首先,按需...

  • Android自定义ClockView实现时钟效果

    目录 1.效果图 2.分析 3.SurfaceView注意事项 4.实战 5.总结 6.Tips 1.废话不多说先...

  • Canvas绘制时钟效果

    Cnavas绘制时钟 背景图的绘制(大圆、数字、小圆点),掌握基础知识:圆的绘制(arc方法),关于圆的弧度的计算...

  • 仿华为手机时钟

    最近看到华为手机自带的时钟挺漂亮的,就想着自己做一个,先上效果图(不知道怎么传小图) 自定义属性(其实可以有更多自...

  • 自定义LayoutManager仿探探切卡片效果

    探探效果: demo效果如下: LayoutManager自定义 对于自定义LayoutManager我们主要处理...

  • 【Android笔记】android Toast

    1.默认效果: 2.自定义显示位置效果 3.带图片效果 4.完全自定义效果 5.其他线程

  • Android如何实现3D效果

    前言 前段时间读到一篇文章,作者通过自定义View实现了一个高仿小米时钟,其中的3D效果很是吸引我,于是抽时间学习...

网友评论

      本文标题:自定义时钟效果

      本文链接:https://www.haomeiwen.com/subject/vjyzvctx.html