zoukankan      html  css  js  c++  java
  • wing带你玩转自定义view系列(3)模仿微信下拉眼睛



    发现了爱神的自定义view系列,我只想说一个字:凸(艹皿艹 ) !!相见恨晚啊,早看到就不会走这么多弯路了


    另外相比之下我这完全是小儿科。。所以不说了,这篇是本系列完结篇....我要从零开始跟随爱哥脚步去学自定义view了:爱哥自定义view专题


    然后要说的就是  之前的博客都犯了很严重的错误,那就是不要在onDraw里new东西,不要在onDraw里new东西,不要在onDraw里new东西。重要的话说三遍。


    上一篇介绍了 qq未读消息提醒去除效果的简化实现,不知道小伙伴们掌握的怎么样了。


    转载请注明出处:http://write.blog.csdn.net/postedit/50503858


    今天带给大家一个很熟悉的东西,当当当当,就是微信下拉眼睛的实现了。 先看效果图:




    自评相似度  80%  哈哈=  = 。


    用我们一贯的方法来剖析这个view。

    首先 从内到外:

    1.内部其实是两段弧,只不过在改变画笔的宽度。

    2.中间是个圆,一直在改变透明度。

    3.最外面是两条贝塞尔曲线(重点加难点)。


    首先来画静态的眼睛。按照顺序,相信你已经轻车熟路:

                mPaint.setStrokeWidth(10);
                canvas.drawArc(mRectF, 180, 10, false, mPaint);
                canvas.drawArc(mRectF, 205, 25, false, mPaint);
    
                //画圆圈
                mPaint.setStrokeWidth(2);
                canvas.drawCircle(225, 225, 40, mPaint);
                canvas.drawPath(mPath, mPaint);
    

    这样就画出了眼珠的静态部分,然后根据我们的percent大法,分三个阶段:1.弧变粗  2.圆圈透明度改变  3.贝塞尔区限 起点,终点,辅助点改变


    那么将这三个阶段用同一个percent来控制  0-33为1阶段  33-66为2阶段 66-100为3阶段:


    意外收获:当setStrokeWidth 为0时,实际上不是0.

     if(mPercent<33) {//如果为1阶段,改变画笔的大小
    
                float stroke = mPercent/3f;    //用0-33 来控制0-10的变化 计算的方法
                Log.e("wing","st" + stroke);
                if(stroke == 0.0){   //如果为0  则不绘制,这里用背景色解决
                    mPaint.setColor(Color.BLACK);
                }else {
                    mPaint.setColor(Color.GRAY);
                }
                mPaint.setStrokeWidth(stroke);
                canvas.drawArc(mRectF, 180, 10, false, mPaint);
    
    
                canvas.drawArc(mRectF, 205, 25, false, mPaint);
            }else if(mPercent < 66) {     //如果为2阶段  则画静态的1阶段
    
                //画内部
                mPaint.setStrokeWidth(10);
                canvas.drawArc(mRectF, 180, 10, false, mPaint);
                canvas.drawArc(mRectF, 205, 25, false, mPaint);
    
                //画圆圈
                mPaint.setStrokeWidth(2);
                int alpha = (int) ((mPercent - 33f) / 33f * 255);//根据百分比去动态控制透明度的值、
    
                mPaint.setAlpha(alpha);
                canvas.drawCircle(225, 225, 40, mPaint);
    
            }else 


    以上都没什么好说的,现在来说最难的第三阶段(搞了我好久)


    第三阶段全局用一个percent参数,由 66-100演变来的

     float percent = (mPercent-66)*3f/100;


    然后观察曲线的动态变化,是从顶点开始像两侧绘制、这时候很容易想到 根据百分比动态改变起点,终点的值,代码如下:

     float mStartX = 225 -(225-115)*percent;
                float mEndX = 225+ (335-225)*percent;
    
                mTopPath.moveTo(mStartX ,175+(225-175)*percent);
    //            Log.e("wing","start:"+(225 -(225-145)*percent) + " y:"+125+(225-125)*percent);
                mTopPath.quadTo(225, 175, mEndX, 175+(225-175)*percent );
    
                canvas.drawPath(mTopPath, mPaint);
    然后你会惊奇的发现如下效果:

    这是因为只改变了起终点,并没有改变辅助点的Y轴。那么辅助点到底应该怎么去改变呢,来看一张图:


    根据之前在  模仿360内存清理效果的研究里发现,  在辅助点x为线段一半的情况下, 弧的切点y轴也为辅助点y的一半。 所以得出 辅助点的Y变化应为:

    175-50*percent

    然后来改写贝塞尔曲线绘制代码:

                float mStartX = 225 -(225-115)*percent;//贝塞尔区限的开始x坐标
                float mEndX = 225+ (335-225)*percent;//贝塞尔区限的结束x坐标
    
                mTopPath.moveTo(mStartX ,175+(225-175)*percent);
    //            Log.e("wing","start:"+(225 -(225-145)*percent) + " y:"+125+(225-125)*percent);
                mTopPath.quadTo(225, 175-50*percent, mEndX, 175+(225-175)*percent );//辅助点的Y坐标动态改变
    
                canvas.drawPath(mTopPath, mPaint);
                mTopPath.reset();
    //
    //            //画静态下边线
    ////            mPath.moveTo(145, 225);
    ////            mPath.quadTo(225, 325, 305, 225);
    ////            canvas.drawPath(mPath, mPaint);
    //
                mPath.moveTo(mStartX ,275-(275-225)*percent);
                mPath.quadTo(225,  275+50*percent, mEndX , 275-(275-225)*percent );
                canvas.drawPath(mPath,mPaint);
    
                mPath.reset();


    最后 给他一个setPercent方法:

       public void setPercent(int percent){
            mPercent = percent;
            invalidate();
        }


    然后在MainActivity内 用seekbar动态改变他的percent值 即可达到我们想要的效果。


    本篇难度较大,请读者动手认真练习,文中坐标可根据个人喜好改变。


    本项目地址:点击打开链接      求star

  • 相关阅读:
    alpha冲刺—Day8
    alpha冲刺—Day7
    alpha冲刺—冲刺计划&代码规范
    Linux安装jdk
    chrome插件开发-notification API注意事项
    VSCode远程连接Docker
    Idea发布项目到Docker
    开发环境配置
    Java设计模式之《单例模式》及应用场景
    使用Docker安装jenkins
  • 原文地址:https://www.cnblogs.com/muyuge/p/6333547.html
Copyright © 2011-2022 走看看