android高仿小米时钟(使用相机和矩阵实现3 d效果)

  

继续练习自定义观点. .毕竟熟才能生巧。一直觉得小米的时钟很精美,那这次就搞它~这次除了练习自定义的观点,还涉及到使用相机和矩阵实现3 d效果。

  

 android高仿小米时钟(使用相机和矩阵实现3 d效果)

  

一个这样的效果,在绘制的时候最好选择一个方向一步一步的绘制,这里我选择由外到内,由深到浅的方向来绘制,代码步骤如下:

  

1,首先老一套~新建attrs.xml文件,编写自定义属性如时钟背景色,亮色(用于分针,秒针,渐变终止色),暗色(圆弧,刻度线,时针,渐变起始色),新建MiClockView继承看来,重写构造方法,获取自定义属性值,初始化涂料、道路以及画圆、弧需要的RectF等东东,重写onMeasure计算宽高,这里不再啰嗦~刚开始学自定义的观点同学建议从我的前几篇博客看起

  

2,由于onSizeChanged方法在构造方法,onMeasure之后,又在onDraw之前,此时已经完成全局变量初始化,也得到了控件的宽高,所以可以在这个方法中确定一些与宽高有关的数值,比如这个视图的半径啊,填充值等,方便绘制的时候计算大小和位置:

        @Override   保护无效alt=" android高仿小米时钟(使用相机和矩阵实现3 d效果)">

  

注意两位数字的宽度和一位数的宽度是不一样的,在计算的时候一定要注意

  

,

        字符串timeText=?2”;   mTextPaint。getTextBounds (timeText 0 timeText.length (), mTextRect);   int textLargeWidth=mTextRect.width();//两位数字的宽   mCanvas。drawText (“12”, getWidth ()/2 - textLargeWidth/2, mPaddingTop + mTextRect.height (), mTextPaint);   timeText=?”;   mTextPaint。getTextBounds (timeText 0 timeText.length (), mTextRect);   int textSmallWidth=mTextRect.width();//一位数字的宽   mCanvas。drawText (“3”, getWidth () - mPaddingRight mTextRect.height ()/2 - textSmallWidth/2,   获得()/2 + mTextRect.height ()/2, mTextPaint);   mCanvas。drawText (“6”, getWidth ()/2 - textSmallWidth/2,获得()——mPaddingBottom mTextPaint);   mCanvas。drawText (“9”, mPaddingLeft + mTextRect.height ()/2 - textSmallWidth/2,   获得()/2 + mTextRect.height ()/2, mTextPaint);   之前      

我计算文本的宽高一般采用的方法是,新的一个矩形,然后再绘制时调用

        mTextPaint。getTextBounds (timeText 0 timeText.length (), mTextRect);      

将这个文本的范围赋值给这个mTextRect,此时mTextRect.width()就是这段文本的宽,mTextRect.height()就是这段文本的高。

  

 android高仿小米时钟(使用相机和矩阵实现3 d效果)

  

画文本旁边的四个弧:

        mCircleRectF。集(mPaddingLeft + mTextRect.height ()/2 + mCircleStrokeWidth/2,   mPaddingTop + mTextRect.height ()/2 + mCircleStrokeWidth/2,   - mPaddingRight mTextRect.height getWidth () ()/2 + mCircleStrokeWidth/2,   获得()- mPaddingBottom mTextRect.height ()/2 + mCircleStrokeWidth/2);   for (int i=0;我& lt;4;我+ +){   mCanvas。drawArc (mCircleRectF 5 + 90 *我,80,假,mCirclePaint);   }      

计算圆弧外接矩形的范围别忘了加上圆弧线宽的一半

  

4,再往里是刻度盘,画这个刻度盘的思路是现在底层画一个mScaleLength宽度的圆,并设置SweepGradient渐变,上面再画一圈背景色的刻度线。获得SweepGradient的矩阵对象,通过不断旋转mGradientMatrix的角度实现刻度盘的旋转效果:

     /* *   *画一圈梯度渲染的亮暗色渐变圆弧,重绘时不断旋转,上面盖一圈背景色的刻度线   */私人空间drawScaleLine () {   mScaleArcRectF。集(mPaddingLeft + 1.5 f * mScaleLength + mTextRect.height ()/2,   mPaddingTop + 1.5 f * mScaleLength + mTextRect.height ()/2,   - mPaddingRight mTextRect.height getWidth () ()/2 - 1.5 f * mScaleLength,   获得()- mPaddingBottom mTextRect.height ()/2 - 1.5 f * mScaleLength);//矩阵默认会在三点钟方向开始颜色的渐变,为了吻合//钟表十二点钟顺时针旋转的方向,把秒针旋转的角度减去90度   mGradientMatrix。setRotate (mSecondDegree - 90, getWidth()/2,获得()/2);   mSweepGradient.setLocalMatrix (mGradientMatrix);   mScaleArcPaint.setShader (mSweepGradient);   mCanvas。drawArc (mScaleArcRectF 0 360,假,mScaleArcPaint);//画背景色刻度线   mCanvas.save ();   for (int i=0;我& lt;200;我+ +){   mCanvas.drawLine (getWidth ()/2, mPaddingTop + mScaleLength + mTextRect.height ()/2,   getWidth ()/2, mPaddingTop + 2 * mScaleLength + mTextRect.height ()/2, mScaleLinePaint);   mCanvas.rotate (1.8 f, getWidth()/2,获得()/2);   }   mCanvas.restore ();   }      

android高仿小米时钟(使用相机和矩阵实现3 d效果)