美文网首页
仿华为手机时钟

仿华为手机时钟

作者: 言吾許 | 来源:发表于2018-03-20 17:21 被阅读0次

    最近看到华为手机自带的时钟挺漂亮的,就想着自己做一个,先上效果图(不知道怎么传小图)


    华为手机自带钟表.gif
    自定义view实现.gif

    自定义属性(其实可以有更多自定义属性):

    <!--仿华为时钟-->
        <declare-styleable name="HuaWeiClock">
            <!--背景颜色-->
            <attr name="backgroundColor" format="color" />
            <!--竖线颜色-->
            <attr name="secondLineColor" format="color" />
            <!--秒针点的颜色-->
            <attr name="secondPointColor" format="color" />
            <!--时间的颜色-->
            <attr name="timeColor" format="color" />
        </declare-styleable>
    

    自定义view:

    public class HuaWeiClock extends View {
        /**
         * 背景颜色
         */
        private int backgroundColor;
        /**
         * 秒针竖线的颜色
         */
        private int secondLineColor;
        /**
         * 秒针红色点的颜色
         */
        private int secondPointColor;
        /**
         * 时间的颜色
         */
        private int timeColor;
    
        private Paint mPaint;
    
        /**
         * 背景宽度
         */
        private int widthBg;
        /**
         * 背景高度
         */
        private int heightBg;
        /**
         * 钟表半径
         */
        private int watchRadius;
        /**
         * 秒针红点的半径
         */
        private static final int SECOND_POINT_RADIUS = 20;
        /**
         * 线最长的长度
         */
        private static final int LINE_MAX_LENGTH = 60;
        /**
         * 线最短的长度
         */
        private static final int LINE_MIN_LENGTH = 30;
        /**
         * 秒刻度白线的数量
         */
        private static final int LINE_COUNT = 120;
    
        /**
         * 每根针占的角度
         */
        private static final int ONE_LINE_ANGLE = 360 / LINE_COUNT;
    
        /**
         * 秒针的角度
         */
        private float angle;
    
        private String time = "00:00";
    
        /**
         * 长于普通秒针刻度的驼峰一侧的条数
         */
        private static final int LONG_LINE_COUNT = 7;
        /**
         * 一侧7根长针的角度
         */
        private static final int LONG_LINES_ANGLE = ONE_LINE_ANGLE * LONG_LINE_COUNT;
    
    
        public HuaWeiClock(Context context) {
            this(context, null);
        }
    
        public HuaWeiClock(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public HuaWeiClock(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.HuaWeiClock);
            backgroundColor = typedArray.getColor(R.styleable.HuaWeiClock_backgroundColor, Color.parseColor("#003560"));
            secondLineColor = typedArray.getColor(R.styleable.HuaWeiClock_secondLineColor, Color.WHITE);
            secondPointColor = typedArray.getColor(R.styleable.HuaWeiClock_secondPointColor, Color.parseColor("#CE3228"));
            timeColor = typedArray.getColor(R.styleable.HuaWeiClock_timeColor, Color.WHITE);
            typedArray.recycle();
            initPaint();
            startTime();
        }
    
    
        /**
         * 初始化画笔
         */
        private void initPaint() {
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
        }
    
        /**
         * 获取时间,并通过RxJava实现动画
         */
        private void startTime() {
            //延时0秒后每隔100毫秒,刷新一次UI
            Observable.interval(0, 100, TimeUnit.MILLISECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {
                            Calendar calendar = Calendar.getInstance();
                            int second = calendar.get(Calendar.SECOND);
                            int milliSecond = calendar.get(Calendar.MILLISECOND);
                            angle = (float) (second * 1000 + milliSecond) * 6 / 1000f;
                            SimpleDateFormat minuteFormat = new SimpleDateFormat("HH:mm");
                            time = minuteFormat.format(calendar.getTime());
                            postInvalidate();
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            Logger.d(throwable.getMessage());
                        }
                    });
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int width = 0;
            int height = 0;
            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    
            switch (widthMode) {
                case MeasureSpec.AT_MOST:
                    width = widthSize * 3 / 4;
                    break;
                case MeasureSpec.EXACTLY:
                    width = widthSize;
                    break;
                case MeasureSpec.UNSPECIFIED:
                    break;
                default:
                    break;
            }
            switch (heightMode) {
                case MeasureSpec.AT_MOST:
                    height = heightSize / 2;
                    break;
                case MeasureSpec.EXACTLY:
                    height = heightSize;
                    break;
                case MeasureSpec.UNSPECIFIED:
                    break;
                default:
                    break;
            }
            widthBg = width;
            heightBg = height;
            watchRadius = height * 2 / 5;
            setMeasuredDimension(width, height);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            drawBg(canvas);
            drawTickMark(canvas);
            drawSecondPoint(canvas);
            drawTime(canvas);
        }
    
        /**
         * 画背景
         *
         * @param canvas 画板
         */
        private void drawBg(Canvas canvas) {
            mPaint.setColor(backgroundColor);
            mPaint.setStyle(Paint.Style.FILL);
            RectF rectBg = new RectF(0, 0, widthBg, heightBg);
            canvas.drawRect(rectBg, mPaint);
        }
    
        /**
         * 画刻度线
         *
         * @param canvas 画板
         */
        private void drawTickMark(Canvas canvas) {
            mPaint.setColor(secondLineColor);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(3);
            for (int i = 0; i < LINE_COUNT; i++) {
                //角度差的绝对值
                float absoluteValue = Math.abs(i * ONE_LINE_ANGLE - angle);
                //求  刻度针线 和 秒针 之间的角度(小于180度)
                float differenceAngle = absoluteValue <= 180 ? absoluteValue : 360 - absoluteValue;
                //大于七根长线刻度的线,那么长度固定
                if (differenceAngle > LONG_LINES_ANGLE) {
                    canvas.drawLine(widthBg / 2, heightBg / 2 - watchRadius, widthBg / 2, heightBg / 2 - watchRadius + LINE_MIN_LENGTH, mPaint);
                    canvas.rotate(3, widthBg / 2, heightBg / 2);
                } else {
                    canvas.drawLine(widthBg / 2, heightBg / 2 - watchRadius - (1 - differenceAngle / LONG_LINES_ANGLE) * (LINE_MAX_LENGTH - LINE_MIN_LENGTH), widthBg / 2, heightBg / 2 - watchRadius + LINE_MIN_LENGTH, mPaint);
                    canvas.rotate(3, widthBg / 2, heightBg / 2);
                }
            }
        }
    
        /**
         * 画秒表的红点
         *
         * @param canvas 画布
         */
        private void drawSecondPoint(Canvas canvas) {
            mPaint.setColor(secondPointColor);
            mPaint.setStyle(Paint.Style.FILL);
            int secondPointRadiusBig = watchRadius - LINE_MIN_LENGTH - SECOND_POINT_RADIUS - 20;
            double pointAngle = angle * Math.PI / 180;
            canvas.drawCircle((float) (widthBg / 2 + secondPointRadiusBig * Math.sin(pointAngle)), (float) (heightBg / 2 - secondPointRadiusBig * Math.cos(pointAngle)), SECOND_POINT_RADIUS, mPaint);
        }
    
        /**
         * 画时间
         *
         * @param canvas 画布
         */
        private void drawTime(Canvas canvas) {
            mPaint.setColor(timeColor);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setTextSize(widthBg / 7);
            Rect bounds = new Rect();
            mPaint.getTextBounds(time, 0, time.length(), bounds);
            Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
            int baseline = (getMeasuredHeight() - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
            canvas.drawText(time, getMeasuredWidth() / 2 - bounds.width() / 2, baseline, mPaint);
        }
    }
    
    

    最后在布局文件中引入:

     <com.xu.helloworld.HuaWeiClock
            android:id="@+id/huaWeiClock"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:backgroundColor="#003560"
            app:secondLineColor="@android:color/white"
            app:secondPointColor="#CE3228"
            app:timeColor="@android:color/white" />
    

    收工~~~

    相关文章

      网友评论

          本文标题:仿华为手机时钟

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