发现了爱神的自定义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

wing带你玩转自定义view系列(3)模仿微信下拉眼睛的更多相关文章

  1. wing带你玩转自定义view系列(2) 简单模仿qq未读消息去除效果

    上一篇介绍了贝塞尔曲线的简单应用 仿360内存清理效果 这一篇带来一个  两条贝塞尔曲线的应用 : 仿qq未读消息去除效果. 转载请注明出处:http://blog.csdn.net/wingicho ...

  2. wing带你玩转自定义view系列(1) 仿360内存清理效果

    本篇是接自 手把手带你做自定义view系列 宗旨都是一样,带大家一起来研究自定义view的实现,与其不同的是本系列省去了简单的坐标之类的讲解,重点在实现思路,用简洁明了的文章,来与大家一同一步步学习. ...

  3. 自定义View系列教程05--示例分析

    站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Android多分辨率适配框架(3)- 使用指南 自定 ...

  4. 自定义View系列教程04--Draw源码分析及其实践

    深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Andr ...

  5. 自定义View系列教程01--常用工具介绍

    站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Android多分辨率适配框架(3)- 使用指南 自定 ...

  6. 自定义View系列教程08--滑动冲突的产生及其处理

    深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Andr ...

  7. 自定义View系列教程07--详解ViewGroup分发Touch事件

    深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Andr ...

  8. 自定义View系列教程06--详解View的Touch事件处理

    深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Andr ...

  9. 自定义View系列教程03--onLayout源码详尽分析

    深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Andr ...

随机推荐

  1. Java日志-Log4j2

    Log4j2参考资料 Log4j2 官方配置文档 1. Log4j2基本概念: Logger 在代码中产生日志信息的.比如logger.info("some log message" ...

  2. Android简易实战教程--第四十八话《Android - Timer、TimerTask和Handler实现倒计时》

    之前本专栏文章中的小案例有写到:第三十九话<Chronometer实现倒计时> 以及使用异步实现倒计时:第三十三话< AsyncTask异步倒计时> 本篇文章 结合Timer. ...

  3. 2017腾讯校招面试回忆(成功拿到offer)

    我本来报的岗位是企业事业群,后来把我分配到了技术工程群 希望对明年找工作的朋友们能有一点帮助 一面 21号 大概1小时 面试半小时 聊天半小时 1 二叉树的查找 我大笔一挥,在纸上写下了下面的的代码 ...

  4. 剑指Offer——知识点储备-操作系统基础

    剑指Offer--知识点储备-操作系统基础 操作系统 操作系统什么情况下会出现死锁? 产生死锁的必要条件 (1)互斥条件:即某个资源在一段时间内只能由一个进程占有,不能同时被两个或两个以上的进程占有, ...

  5. 软件测试之BUG分析定位概述(QA如何分析定位BUG)

    你是否遇到这样的场景? QA发现问题后找到DEV说: 不好了,你的程序出问题了! DEV(追查半小时之后): 唉,是你们测试环境配置的问题 唉,是你们数据不一致 唉,是你们**程序版本不对 唉,是** ...

  6. android 网络获取json并且显示(2)

    1.将要的取得的json数据格式如下: 我们封装之前的类用google提供的JSONArray和JSONObject类对json字符串进行解析. 对于姚明显示每一条数据,我们封装了一个类如下: pub ...

  7. EJB通过注解方式注入并使用其他EJB或者服务、配置JBoss数据源

    通过注解方式注入并使用其他EJB或者服务 真实项目EJB对象很多,EJB之间也可以互相调用, 在项目HelloWorld下新建接口Other在cn.hqu.ejb3下: public interfac ...

  8. 利用cocos2d-x实现CandyCrushSaga消除功能

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=455 昨天没事写了个三消玩玩.已 ...

  9. Java基础---Java---IO流-----BufferedReader、BufferedWriter、缓冲区、装饰设计模式及和继承的区别

    IO流 IO流用来处理设备之间的数据传输 java对数据的操作是过流的方式 流按操作数据分为两种:字节流与字符流 流按流向分为:输入流,输出流. IO流常用基类 字节流的抽象基类:InputStrea ...

  10. android打包引用第三方jar出现的错误

    今天终于完成了近一个月的App开发工作,对程序进行混淆导出签名apk包时,却出现了如下的错误: Proguard returned with error code 1. See console Not ...