一个炫字都不够??!!!手把手带你打造3D自定义view

来源:互联网 发布:node forever log 编辑:程序博客网 时间:2024/05/16 05:04

分享一则最近流行的笑话: 
最新科学研究表明:寒冷可以使人保持年轻,楼下的王大爷表示虽然今年已经60多岁了,但是仍然冷的跟孙子一样。

呃。好吧,这个冬天确实有点冷,在广州活生生的把我这个原生北方人,冻成一条狗。(研究表明:寒冷可以让人类基因突变。。。。)

好了不扯了。前些日子有朋友让我写博客来分析一下这个仿MIUI的时钟,从中学到了一些炫酷效果的实现。 
https://github.com/AvatarQing/MiClockView 感谢原作者的开源精神!

那么是啥3D效果呢,先来看看效果图,额。。有好多个: 
这里写图片描述 
这里写图片描述 
这里写图片描述

其实后两个都是png来的。。

转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50590051

那么请问,看到图形的变换,你想到了什么? 
没错!就是Matrix。 
关于Matrix你可以到爱哥的博客了解到及其详细的讲解(谢谢爱哥!)。

下面我们就来研究一下如何用矩阵,实现这个3d的效果。

首先新建自定义view类。

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">TDView</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">View</span> {</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Paint mPaint;    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> mCenterX;    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> mCenterY;     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">TDView</span>(Context context, AttributeSet attrs) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context, attrs);        mPaint = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Paint();    }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

然后在圆心画一个圆出来

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onDraw</span>(Canvas canvas) {        mCenterX = getWidth() / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;        mCenterY = getHeight() / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;        canvas.drawCircle(mCenterX,mCenterY,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>,mPaint);    }    ```现在是这样的: ![这里写图片描述](http:<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//img.blog.csdn.net/20160126235856787)</span>我们知道,处理一个图片的时候(切错)可以使用矩阵来处理,同时处理X,Y的话可以使用Camera类,camera可以生成一个指定效果的矩阵。直接来看用法:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Camera mCamera;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Matrix mMatrix;mMatrix = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Matrix();mCamera = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Camera();在onDraw里 把camera给旋转一下,并把生成的矩阵给一个矩阵。再把矩阵应用到canvas,看一下效果。</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>
    mMatrix.reset();    mCamera.save();    mCamera.rotateX(10);    mCamera.rotateY(20);    mCamera.getMatrix(mMatrix);    mCamera.restore();    //将矩阵作用于整个canvas    canvas.concat(mMatrix);    ```

这里写图片描述 
这里写图片描述 
呃。。。确实是变形了。。但是好像不是我们想要的结果? 
这是因为,矩阵的变换坐标总从左上角(0,0)开始。所以我们要把变换的坐标改为中心点,方法如下:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">        mMatrix<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.reset</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        mCamera<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.save</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        mCamera<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.rotateX</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        mCamera<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.rotateY</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        mCamera<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getMatrix</span>(mMatrix)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        mCamera<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.restore</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        //改变矩阵作用点        mMatrix<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.preTranslate</span>(-mCenterX, -mCenterY)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        mMatrix<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.postTranslate</span>(mCenterX, mCenterY)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        canvas<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.concat</span>(mMatrix)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        ```此时的效果看起来像是向左倾斜了: 这里写图片描述![这里写图片描述](http://img<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.blog</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.csdn</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.net</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20160127001356605</span>)接下来让他跟随手指移动,重写onTouchEvent:</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>

@Override 
public boolean onTouchEvent(MotionEvent event) { 
float x = event.getX(); 
float y = event.getY();

    int action = event.getActionMasked();    switch (action) {        case MotionEvent.ACTION_MOVE: {            //这里将camera旋转的变量赋值            mCanvasRotateY = y;            mCanvasRotateX = x;            invalidate();            return true;        }        case MotionEvent.ACTION_UP: {            //这里将camera旋转的变量赋值            mCanvasRotateY = 0;            mCanvasRotateX = 0;            invalidate();            return true;        }    }    return super.onTouchEvent(event);}```

哈哈。。看看是什么效果: 
这里写图片描述 
这里写图片描述

什么鬼,怎么跟转硬币一样。 因为旋转的X,Y给的太大了呗。所以要约束一下。

定义一个旋转最大值

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> mCanvasMaxRotateDegree = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>; </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

再用percent思想(前面博客有提到),来处理手指触摸点和这个度数变化的关系:

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> rotateCanvasWhenMove(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> x, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> y) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> dx = x - mCenterX;        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> dy = y - mCenterY;        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> percentX = dx / mCenterX;        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> percentY = dy /mCenterY;        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (percentX > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1f</span>) {            percentX = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1f</span>;        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (percentX < -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1f</span>) {            percentX = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1f</span>;        }        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (percentY > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1f</span>) {            percentY = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1f</span>;        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (percentY < -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1f</span>) {            percentY = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1f</span>;        }        mCanvasRotateY = mCanvasMaxRotateDegree * percentX;        mCanvasRotateX = -(mCanvasMaxRotateDegree * percentY);    }    ```最后将TouchEvent里面的ACTION_MOVE 调用此函数即可。 此时,完整的代码如下:</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>
private int mCenterX;private int mCenterY;private float mCanvasRotateX = 0;private float mCanvasRotateY = 0;private float mCanvasMaxRotateDegree = 20;private Matrix mMatrix = new Matrix();private Camera mCamera = new Camera();private Paint mPaint;public TDView(Context context) {    super(context);}public TDView(Context context, AttributeSet attrs) {    super(context, attrs);    mPaint = new Paint();    mCanvasMaxRotateDegree = 20;}@Overrideprotected void onDraw(Canvas canvas) {    mCenterX = getWidth() / 2;    mCenterY = getHeight() / 2;    rotateCanvas(canvas);    canvas.drawCircle(mCenterX, mCenterY, 100, mPaint);}private void rotateCanvas(Canvas canvas) {    mMatrix.reset();    mCamera.save();    mCamera.rotateX(mCanvasRotateX);    mCamera.rotateY(mCanvasRotateY);    mCamera.getMatrix(mMatrix);    mCamera.restore();    mMatrix.preTranslate(-mCenterX, -mCenterY);    mMatrix.postTranslate(mCenterX, mCenterY);    canvas.concat(mMatrix);}@Overridepublic boolean onTouchEvent(MotionEvent event) {    float x = event.getX();    float y = event.getY();    int action = event.getActionMasked();    switch (action) {        case MotionEvent.ACTION_DOWN: {            rotateCanvasWhenMove(x, y);            return true;        }        case MotionEvent.ACTION_MOVE: {            rotateCanvasWhenMove(x, y);            invalidate();            return true;        }        case MotionEvent.ACTION_UP: {            mCanvasRotateY = 0;            mCanvasRotateX = 0;            invalidate();            return true;        }    }    return super.onTouchEvent(event);}private void rotateCanvasWhenMove(float x, float y) {    float dx = x - mCenterX;    float dy = y - mCenterY;    float percentX = dx / mCenterX;    float percentY = dy /mCenterY;    if (percentX > 1f) {        percentX = 1f;    } else if (percentX < -1f) {        percentX = -1f;    }    if (percentY > 1f) {        percentY = 1f;    } else if (percentY < -1f) {        percentY = -1f;    }    mCanvasRotateY = mCanvasMaxRotateDegree * percentX;    mCanvasRotateX = -(mCanvasMaxRotateDegree * percentY);}

}

<code class="hljs markdown has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">简简单单100行代码,实现了3D效果的view: ![<span class="hljs-link_label" style="box-sizing: border-box;">这里写图片描述</span>](<span class="hljs-link_url" style="box-sizing: border-box;">http://img.blog.csdn.net/20160127002811543</span>)接下来做什么呢? 当然是把这个效果加到我们的自定义view里面! 比如,把我的PanelView加上这个效果: 这里写图片描述 ![<span class="hljs-link_label" style="box-sizing: border-box;">这里写图片描述</span>](<span class="hljs-link_url" style="box-sizing: border-box;">http://img.blog.csdn.net/20160127003536598</span>)哗!瞬间高大上!那么,你要不要跟我趁热来一发自定义view? 说搞就搞!在原有类上进行修改 给一个好看的底色,画一条线</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>
    mBgColor = Color.parseColor("#227BAE");    canvas.drawLine(mCenterX,100,mCenterX,130,mPaint);    ```

这里写图片描述 
这里写图片描述 
嗯。不错 有条线了。微调下间距,旋转画布,画出整个圆形来:

<code class="hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//保存坐标系 </span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.save(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">120</span>; i++) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">rotate</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>,mCenterX,mCenterY); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.drawLine(mCenterX, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">150</span>, mCenterX, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">170</span>, mPaint); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//恢复坐标系 </span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.restore(); </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

这里写图片描述 
嗯。。看起来想点样子了。 接下来调整透明度。

<code class="hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.save();        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">120</span>; i++) {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//根据i调整透明度alpha</span>            mPaint.setAlpha(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255</span>-(mAlpha * i/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">120</span>));            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.drawLine(mCenterX, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">150</span>, mCenterX, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">170</span>, mPaint);            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">rotate</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>,mCenterX,mCenterY);        }        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.restore();</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

这里写图片描述 
哈哈。。有没有点意思呢。。 
这里写图片描述 
我们画个圆球上去!画之前先ctrl + alt + m 把之前画弧的方法提出来。 
画一个紧挨着的圆

private void drawCircle(Canvas canvas) { 
mPaint.setAlpha(255); 
canvas.drawCircle(mCenterX,213,10,mPaint); 

这里写图片描述 
这里写图片描述 
不错不错,给点动态效果吧,让圆点跟着我们触摸的地方走。怎么做呢。。 当然还是旋转画布了! 
这里需要注意的是触摸点与12点钟方向形成的夹角计算。画图分析一下 
这里写图片描述 
可以看到 我们只需要调用Math.atan方法即可算出a的弧度,再将其转换为角度即可,在进行3D旋转之前,旋转画布:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onDraw</span>(Canvas canvas) {        canvas.drawColor(mBgColor);        mCenterX = getWidth() / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;        mCenterY = getHeight() / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;        Log.e(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wing"</span>,alpha+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>);        canvas.rotate((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span>) alpha,mCenterX,mCenterY);        alpha = Math.atan((mTouchX-mCenterX)/(mCenterY-mTouchY));        alpha = Math.toDegrees(alpha);        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(mTouchY>mCenterY){            alpha = alpha+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">180</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>

现在看一下效果: 
这里写图片描述 
这里写图片描述

效果出来了,但是还美中不足呀。 因为中间太空了,所以这个3D效果看起来有点奇怪。那就给他中间加点东西吧! 比如一个指针。

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">private void drawPath(Canvas canvas) {        mPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.moveTo</span>(mCenterX,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">223</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        mPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lineTo</span>(mCenterX-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">30</span>,mCenterY)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        mPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lineTo</span>(mCenterX,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>*mCenterY-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">223</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        mPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lineTo</span>(mCenterX+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">30</span>,mCenterY)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        mPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lineTo</span>(mCenterX,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">233</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        mPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.close</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        canvas<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.drawPath</span>(mPath,mPaint)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        mPaint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setColor</span>(Color<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.parseColor</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"#55227BAE"</span>))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        canvas<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.drawCircle</span>(mCenterX,mCenterY,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>,mPaint)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

最后大功告成!!! 看效果! 
这里写图片描述 
这里写图片描述

如果你喜欢我的博客,请点击关注。欢迎评论~~

下一篇! 手把手教你做一个qq下拉抢红包:打开链接

0 0
原创粉丝点击