这句话我真的憋了很久。Android 工程师只要关注我,我就能让你达到大师级水平,不是面试时的吹牛逼水平,不是自我欺骗的了解皮毛的水平,是真正的开发实力。之前我有这个自信,没这个证据。但如今,证据我也有了。java
关注个人人都知道,我这三个多月来一直在网上分享关于 Android 自定义绘制的技术,而且在一周多前举办了一场线上的「仿写酷应用」活动,让个人粉丝仿写即刻、薄荷健康、小米运动、Flipboard 这四个软件中的几个经典效果,来自我验证一下这三个月来的学习成果。android
简单地说,这事儿很成功(脸红)。git
通过一周的投稿时间,共收到 97 份来自关注者的投稿(真的不少,出乎意料),并且作得都很棒。在四位原开发者的艰难筛选下,每一个效果选出了一位优胜者。下面就是这四位优胜者的做品以及来自各位原开发者对他们的点评。程序员
二话不说,先看结果。github
原效果:面试
仿写效果:算法
仿得很细致有没有。并且,这个仿写效果看似简单,实际上是假象。它右边的数字跳动,是一个字符一个字符跳动替换的,而不是整个字符串一块儿被替换掉,这个须要对文字绘制的 API 有足够的熟悉才能作到。编程
这位仿写者叫刘金伟。在通知刘金伟成为「被选中的人」后,我对他进行了一个简短的微信采访。关于此次仿写的过程,刘金伟是这样对我说的:canvas
到此次仿写活动为止,HenCoder专栏已经出了8篇View绘制相关的技术文章了,每篇文章认真阅读以后我也根据例子进行实践操做,学到的一些东西也在项目开发中得以应用,正如文章中所说,在自定义View相关方面更加自如了。微信
看到此次HenCoder的仿写活动,就有点跃跃欲试,发现这几个效果都挺不错的,和朋友聊了聊以后就选了这个常常会用到的点赞功能进行实践。这个点赞效果通过我分析发现虽然内部动画挺多,可是所用到的技术点都是在HenCoder中讲到过的,因此在简单的分析以后就开始写,大约花了大半天时间就基本完成了,整个过程也没太多技术难点,作出来后还给朋友炫耀了一番。
最后再次由衷的感谢HenCoder专栏,为了提高你们技术水平而作的事,很是敬佩。
不谢不谢,哈哈。
对他的做品进行点评的是即刻的 Android Leader 罗琼。他对这份仿写的评价彷佛还不错:
仿写效果的点评,主要针对如下几点
对原创的还原程度
示例的完备程度(可测试性)
项目规范
代码实现
对原创的还原程度
这位同窗仔细观察了即刻点赞效果
使用的资源应该是反编译即刻 apk 以后拿到的
实现了点赞和取消点赞两种效果
实现了左边图片部分的动画
实现了右边数字部分的动画
未实现的部分
点赞对 touch 操做的处理(只处理了 click 操做)
点赞效果在图片上的先放大后缩小
散开的点的放大效果
总体动画的细节优化
示例的完备程度
这个是作得比较好的
能够直接设置具体数字,这样方便作边界条件(进位退位)的测试。
上传了能够直接安装的 app-release.apk ,方便先安装看效果。
README 有对动画实现的说明。
项目规范
没有 .idea 这种不应上传的文件夹
.gitignore 也是专门修改过的
能够优化的部分
对 android support 包的依赖,不要依赖 alpha 这种版本,尽可能依赖稳定版
代码文件都须要进行格式化,包括 xml
mdpi 的资源再也不须要了
自定义 View 的 attr 的命名,须要有本身的命名空间(前缀)
自定义 View 的变量命名不规范,一下子有 m ,一下子有下划线
代码实现
做者把图片和文字写在一个类里面了,这样的话不太灵活,即刻 app 如今在某些主题下的点赞效果不是大拇指,好比逝者这个主题就是蜡烛,因此建议图片和文字仍是分红两个类来搞。
对点击事件的防重处理好像有点问题,另外连续点击是否直接对以前动画进行 cancel 也须要斟酌一下。
总体的实现代码上冗余逻辑比较多,而且每个函数内部每一行语句并无彻底去考虑,如对 specMode 的 switch case ,没有穷尽全部的可能值。
图片这块的实现,总体的思路是经过事先画好各类元素,而后经过属性动画的方式,但自定义的属性动画的方法是经过反射调用的,整个类里面并无显示调用,对于> 此类不是很复杂的动画,建议仍是用系统自带的属性比较好。
文字这块的实现,涉及到偏移、颜色、以及分离出变化和不变的部分(做者对文字的解剖分析得很好),但代码的复用程度不高。
整体而言,项目完成度比较高,恭喜得到本次仿写即刻点赞效果的冠军,不过真正商用的话仍是有很多须要考虑的,尤为是代码规范上须要增强,再好的实现和算法,若是代码不够规范,恐怕看得人也会比较累,但愿再接再砺。
评价得好详细啊,我在读这份点评的过程当中屡次遇到「哇塞好细,若是是个人话这里确定要被扣分了」的状况。
依然是先上效果:
原效果:
仿写效果:
以假乱真了有没有?
这份仿写的做者叫严积楷。他对仿写过程的回顾是这样的:
我以为仿写,首先就是要了解清楚仿写对象的细节,因此仍是本身亲自体验一下比较好,因此就下载了薄荷健康APP,发现尺子UI已经改变了(这样就提醒了我要作一个适合多变需求的控件),可是一些特性也是和效果图差很少的:触摸滑动后是有惯性滚动的光标保持在中间,不随尺子滚动光标选中的刻度只会是0.1整点让触摸滑动、惯性滚动以后,尺子会回滚到最近的整点刻度,如最后滑动到66.5和66.6中间靠右,则回滚到66.6。
了解了特性以后,就是想着怎样实现了:首先就是画出刻度和数字,这里是采用一会儿就画出全部刻度的方法,而后经过滑动方法scrollBy()来移动画面(不知道这样系统会不会对尺子那些不在屏幕显示的部分进行绘画计算的,我当时是加上滑动以后,发现很能够滑的流畅,因此就这样了,如今想一想还能够处理一下的)。触摸控制方面,由于以前分析过GestureDetector,了解了它的实现,因此这里就试着直接重写onTouchEvent()和OverScroller配合实现惯性滑动。对于刻度的计算,这里经过滑动位置getScrollX()来计算当前刻度,而又经过把滑动结束后的刻度四舍五入以后,计算对应的ScrollX来让尺子最近的整0.1点刻度。对于光标的绘制,因为这里是采用了scrollBy()的方法移动画面,因此也没有找到一个好的方法让光标不随尺子移动,因此就外层加入一个ViewGroup重写dispatchDraw()方法在这里绘制(这个方法执行在onDraw()以后,在这里绘制才不会被尺子的刻度覆盖掉)。
主要的实现思路就是这样了,还有一些细节,如代码封装这些比较常见的就不详细说了,你们能够看代码,已经写好了注释,欢迎指教小弟。
「欢迎指教小弟。」高仿到这种程度居然还求指教,这谦虚的态度莫非是讨打?有人想当面指教他一下吗?
对这份做品进行点评,我请到的是薄荷健康的 Android 工程师 loody。
还原度
99分,多一分怕你骄傲。
实现思路
背景绘制 顶部基准线+纯色背景。
刻度绘制,包括长、短刻度及长刻度下的文字绘制 这块是整个卷尺最复杂的部分,整个卷尺有最大最小边界,因此整个刻度的绘制会基于最大、最小值以及定义的最小刻度单位来从左往右依次绘制,同时要保证当前选中的位置位于屏幕中央。
基准线绘制 位于屏幕中间、能够有多种样式、以上绘制必须按照顺序依次绘制。
手势滑动处理、惯性滑动 经过监测 MotionEvent 里的 ACTION_DOWN、ACTION_MOVE、ACTION_UP、ACTION_CANCEL 事件来监测滑动距离来进行重绘,若是知足Fling,则使用OverScroller来计算速度来进行惯性滑动。
智能精准定位 滑动完以后须要进行精准定位,必须回到基准线最近的刻度,用做者的话就是滑动到66.5和66.6中间靠右,则回滚到66.6。
优势
整个实现的很是好,全部的要点都实现了,特别是精准定位体验作得很棒,在拓展性方面,也定义了不少自定义属性,同时也上传到 Maven 仓库,方便其余人调用。
不足之处
背景和基准线的绘制和刻度的绘制进行了分离,其实不必,由于他们的绘制并无冲突;
在刻度绘制上,屏幕以外的刻度其实能够不用绘制;
卷尺的小刻度模式能够再丰富一些,通常两个大刻度之间有10个小刻度,固然也有2个、5个状况;
对外开放的初始化方法应该更丰富一些,由于不少时候咱们的边界值并非固定的。
薄荷的卷尺效果要实现起来是有很是多的细节的。loody 要从几十份仿写中选出这一份,还要写出这么细致的点评,别的我不想说,我只想对他说一句:苦了你了。另外也更想回头对上面的仿写者严积楷说一句:你太苦了!
原效果:
仿写效果:
仿得也是超棒。这件仿写做品的做者叫陈浩,他的仿写过程回顾充满了认真和辛酸:
以前没有太多作UI的经验,因此一开始我是比较乐观的,但最后花了整整5个晚上才作完。
我编程属于比较严谨(啰嗦)的那种,因此准备工做时我把gif下下来用电脑逐帧看了,还借了朋友的小米手环来看实际的动画(最新版有点出入)。而后把动画流程写下来,没有作什么模块规划,就开始编程了。
最开始动手时我只有动画参数可配置和要作动画状态机的这两个想法,后面整个代码结构都是在编写的过程当中屡次重构产生的。毕竟代码是程序员的第二张脸(我说的),给别人看的时候仍是想写的更好一些。但这也存在一些过分设计的状况,致使完成的时间变长了很多。好比,我看到那个转动的烟花圆环线条不是一成不变的,因而天马行空设计出来一套的动画运动公式:这个线条是椭圆的一段圆弧,其圆心,宽和高的偏移都是随机参数,变化量d由变化速度v决定,变化速度v由外力1.衰减常量力,2.速度平方成正比的阻力,3.定时触发的随机力决定(戏真多)。结果致使动画参数调整就花太多时间,也改了好几版才稳定下来。。
写得好的地方的话,由于工做缘由会比较考虑封装,可维护性,可拓展性这些,这些方面我以为仍是作到位了的。
说实话,在发布仿写征稿文的时候我就知道,确定每一个效果都有人能完成,但陈浩的这份做品仍是让我有点意外:你仿得也太真了!但看了他的这份回顾,我以为我知道为何他写得这么好了。
我很高兴请到了这个效果的原做者,来自小米运动团队的卜冬旭来点评这份做品:
整体评价
至关不错。。。(原本想这四个字完结点评了的,由于模仿的效果类似度很高了,并且仅凭一个gif图,在很短的时间作出这样的效果,真的挺厉害的。同时up主提供的代码里的注释也很清晰,规范,能够很容易理解实现的原理。可是秉着认(wu)真(ren)负(zi)责(di)的态度, 仍是来吹毛求疵一下。)
细节对比
这块的动效是小米运动app首页的效果。示例GIF图中包含了2部分效果,一个是小米手环链接过程当中效果,就是一大堆杂乱的白色渐变的圆圈在转,圆圈的起始位置有一个日后发散的粒子效果。另外一部分就是小米手环链接成功后的效果, 也就是几个白色透明度不等的渐变的圆环叠加在一块儿,最外圈层次渐变的光晕效果围绕圆环转动。
下面具体分析对比下这几块动画效果.圆圈的叠加效果
我这边用了8个圆圈,每一个圆圈的
centerX
,centerY
有微小的差异,半径有微小的差异。经过SweepGradient
来设置它的渐变,从纯白到20%左右透明度的白色,每一个圆圈canvas.rotate
的角度也有微小的差异。固然以上全部参数均可以本身任意调节,来达到良莠不齐的效果, 只要总体效果不离谱就能够了。我对于其中一些参数用的都是random
, 这块没有个标准。杂而不乱, 达到这个效果就行. :D粒子效果
比较麻烦的就是这块粒子效果。一方面要实现功能,一方面性能也要知足,不能卡顿。模仿的效果就这一块有点小问题, 一个是半径有点大了,而后透明度能够稍微降的快一点, 再聚拢一点效果会更好。(坏笑.jpg) 这块调起来是至关的麻烦。 这块粒子产生在第一个效果中圆圈的最亮的地方,也就是透明度最低的地方。具体位置能够从图中看一下。
粒子产生的位置是竖着的线的位置, 也就是随机在这条线上生成初始粒子。 发射的角度大概是左边2个线之间。第一个不是水平线,这两条线的角度能够慢慢的调整,从而找到合适的效果。 须要注意一点的就是, 粒子发射的角度须要比较精细的控制, 具体点说就是由于产生粒子的位置不是一个点,而是一条很短的线,因此尽可能不要让粒子发射的延长线在很短的位置相交, 如图
。
关于粒子发生器的原理这里就不赘述了,我这里是经过距离超过必定数就从新生成一个粒子来控制的,固然也能够经过半径大小或者透明度来控制。Up主是经过透明度来控制的,也是不要紧的。靠近发生器位置的粒子半径稍微大一点,而后半径是递减的。透明度也是递减的。至于性能问题,也不属于这个文章的范围内了。能够看下up主代码。
圆环效果
圆环主体是五个渐变的圆环叠加在一块儿,其实不能算做是圆环,应该是一个圆环和4个椭圆环。 绘制的时候,第一个渐变的圆环正常绘制,后面的椭圆环经过
drawArc
来绘制。保证它们五个环的left
,right
,`bottom
同样,top
参数为依次递增必定的大小。同时须要注意一点的就是颜色最深的圆环,也就是透明度最低的环,不是椭圆环放在最后绘制,这样能够盖住其余稍高透明度的环,这样不会看出叠加部分由于用的SweapGradient
致使的叠加的效果。而是会以为主体是一个整个系统,光晕是独立系统。否则能比较清楚的看出五个环的叠加效果。多余的效果
其实那个总体效果,带有一点上下振动的这块是由于程序的下拉上推致使的,不属于这块的动画效果,没想到也给作出来了。(捂脸.jpg)
这块效果看着挺炫的,其实使用HenCoder里绘图的基础知识就能够实现,麻烦的地方就在于细节的调整, 可能调个参数就要从新跑一下程序, 仍是至关痛苦的。想了解完整的动画效果,能够从仿写的代码里看到, 也能够来这里看。
最后居然被冬旭兄弟打了我一个猝不及防的广告……
[致微信读者]另外,他最后一句提到的「这里」是他的公司华米科技的招聘连接,微信禁止外链因此各位别点了,感兴趣的能够复制一下这个连接: http://www.huami.com/jobs。
原效果:
仿写效果:
这个效果可谓是人气超高了。我在以前的几篇文章或视频中都展现过这个效果,但只是说「用我教的技术就能实现」,却没有展现过具体的实现代码。不少人找我要实现,我也都没给过,为的就是这一天,让个人读者本身实现出来,我只帮你展现。
这个仿写的做者叫贾元斌,它的仿写过程回顾以下:
仿写“翻页效果(增强版)”这个动效的想法,源于凯哥讲解几何变换章节提到的一个动画栗子,很炫酷,极大地激发了偶的好奇心。
作动画的过程,其实就是一个典型的“发现问题,分析问题,解决问题”的过程。因此大概的流程就是,先拆解分析,动画是怎么“动”的,而后再去解决问题,想如何使用Android提供的Api实现“这么动”。 把gif图放在手机上一帧一帧地截屏,而后逐张观察,能够发现这个动画是由三个部分组成的: - 开始动画,一个Y轴三维旋转-45度动效 - 中间动画,比较复杂,图片右半边三维旋转,同时三维旋转的“转轴”平面内旋转了-270度,左半边图不变 - 结束动画,一个绕Y轴三维旋转30度动效 开始和结束的动画比较简单,camera旋转就能实现,重点分析中间的动画: 右半边三维旋转的时候,canvas先旋转,再裁切,再使用camera执行三维动效,而后保存camera效果,最后再旋转回来。问题分析清楚,具体到代码,拿canvas和camera的几何变换+范围裁切,就能实现了。
须要注意的坑:camera执行几何变换时,咱们会把canvas的中心点移动到原点,因此这个时候canvas再执行其余变换(好比范围裁切),要用移动后的坐标系计算。 最后一点,不要忘记作糊脸校订,否则图片尺寸变大时,就无法看了…
贾元斌在最后提到的「糊脸修正」是我本身造的词,我以为好形象啊,佩服本身。
另外,一直找我要实现的,请到文末自取贾兄的源码。
这个点评者我熟悉,我前同事,来自 Flipboard 的段建华(技术小黑屋),之前我在 Flipboard 的时候我俩挨着坐的。
整体点评
运行效果良好,思路比较清晰。总的来讲不错。
思路与实现
在readme文件中给出了具体的实现方案并进行逐步拆分,同时给出了须要的理论分析和一些注意事项
提供了在布局文件中设置图片资源的实现,同时也支持在代码中设置。可扩展性较强
作到动画的执行实现与View分离,便于在不修改代码的状况下,更改动画的配置,好比duration和delay时间等
代码质量
配合以必要的注释,便于理解。
MainActivity中handler.postDelayed已经位于UI线程,无需在进行runOnUiThread调用
对于degreeY等方法使用Keep来注解修饰,既解决了编译器的报警提示也避免了一些由于Proguard优化删除无用方法带来的潜在的问题,这一点体现了做者很周全考虑。
其余
祥云图标的Flipboard Logo很赞
替代的google_map提供了三种dpi对应的资源,+1
改进与完善
MapView 类的javadoc写成“整个动画拆分红了三部分”有些不妥,通常为类的功能介绍
每个commit的提交信息都须要归纳修改的内容,不宜出现简单的update来了事
View命名成MapView,可能存在继续优化改善的空间
Repo的命名建议更加和参赛做品有关,这样便于筛选人员更好的快速辨识并分发给对应的评委。
看了建华的评价,我最大的感觉就是,他果真仍是这么认真,一些很细节的地方他也都提到了。另外多是出于谨慎考虑,建华对于这份仿写实现和 Flipboard 的内部代码实现没有进行比对。而我做为一个已经离职的员工,我就……固然也不会泄露前公司的源码啦。但我要特别说明一下的是,贾元斌的仿写代码中的实现虽然和 Flipboard 的内部实现不彻底同样,但执行效率和代码可读性都不比 Flipboard 的实现差。
至于 Flipboard 的内部实现究竟是怎样的?我就不告诉你……
上期内容我说过,因为赞助方爸爸 insight.io 的支持,此次活动的四位优胜者中,还会有一位特别优胜者,他得到的奖品和另外三位不同,他将得到一步 Google Clips 相机:
这位优胜者将经过微博投票得出,投票连接:http://vote.weibo.com/poll/138417225
微信用户能够点下面的「阅读原文」来投票。
几位仿写者的仿写代码连接在这里。这里贴的是 insight.io 从 github 同步的代码库,用 insight.io 来读源码超级爽(具体怎么爽,你点开就知道了),真的感谢 insight.io 的在礼物支持以外还给予个人技术支持。
即刻仿写: https://insight.io/github.com/arvinljw/ThumbUpSample/tree/master/
关于仿写者刘金伟:
github: https://github.com/arvinljw
简书: http://www.jianshu.com/u/8fcc3372beb7
薄荷健康仿写: https://insight.io/github.com/totond/BooheeRuler/tree/master/
关于仿写者严积楷:
github: https://github.com/totond
CSDN: http://blog.csdn.net/totond
邮箱: yanzhikai_yjk@qq.com
小米运动仿写: https://insight.io/github.com/SickWorm/MISportsConnectWidget/tree/master/
关于仿写者陈浩:
github: https://github.com/SickWorm
Flipboard 仿写: https://insight.io/github.com/sunnyxibei/HenCoderPractice/tree/master/
关于仿写者贾元斌:
github: https://github.com/sunnyxibei
微博: https://weibo.com/812306989
微信: sun521xibei
我的博客: http://timeriver.com.cn/
想了解几位点评者,想和他们一块儿工做?赶快看这里。
罗琼给了我一份超长的文案,我嫌长想给他删点,可又以为这份文案写得已经超级棒,哪一句都删不得,因此干脆把这份文案最重要的关键词提取了出来,被这些关键词吸引了的能够点下面的连接进去看详情:
即刻的关键词:
流浪猫、400 平米、自带 Gif 表情包文化、健身房、台球桌、无人机、电玩设备、足球队、男女比例平衡、年轻、一年两次免费国内外纯玩 Outing、La Marzocco咖啡机 + Volcan 豆(这个看不懂)、咖啡师、Herman Miller人体工学座椅、公费参加 Google IO & WWDC
好吧我只提取了「福利」部分的关键词,由于我最关心这个……其实即刻团队作的事情更有意思,不过篇幅有限就不给它展现的机会啦(任性脸),有兴趣的能够点连接去看详情:
https://www.v2ex.com/t/388064
哦对了,工做地点上海。
冬旭兄比较委婉地把招聘广告插进了点评的最后(就是上面那句「想了解完整的动画效果,能够从仿写的代码里看到, 也能够来这里看」的「这里」)。不过我仍是要在这里再贴一次他们的招聘连接,让须要的人更清楚地看到:
http://www.huami.com/jobs
「华米科技」,又是一个米。你猜小米旗下到底有多少种米?
个人老同事建华给我发的「广告」是这样的:
这次仿写的参考目标之一为 Flipboard 的折页效果,Flipboard 中国团队目前进行了有史以来最特别、动做最大的一次产品升级改版,推出全新产品——红板报,它将带来更对味的个性化内容推荐、更广阔的全球化新闻视野、更生动的杂志化浏览体验。经过红板报,要将全球最优质的新闻内容用最好看的方式呈现,精简产品功能回归到阅读最核心使命:新闻能够很好看。
嗯,Flipboard 中国改成名红板报以后,做为开发者之一的建华很自豪,也很但愿推荐给你们用。至于招聘连接……建华表示「什么招聘连接?」
Flipboard 北京办公室暂时没有 Android 职位空缺,因此建华实际上是在给他本身打广告(哈哈哈我写了个好 App),你们快去打他呀。
关于招聘,loody 和建华同样对我表示目前没有需求,只是告诉我「能提到薄荷健康就最好了」。
只付出不求回报的好同志。好吧,那我就来负责他们的文案吧:
薄荷健康,真呀真健康,装了薄荷健康,又瘦又健康。耶。
最后很是感谢四位点评者的帮助,此次活动的响应度比个人预期大不少,各位点评者光是审阅投稿就花了一天的时间,审完还要来帮我写点评语,写得短的还要被我打回去重写……真的辛苦了,大家。谢谢!
另外,还要感谢 insight.io 的两位联合创始人李崇哲、赵扶摇,在物质和技术上给我提供支持,让我这第一次本身主持的线上活动少了许多手忙脚乱。固然,也得感谢介绍我与 insight.io 相识的代码家(怎么哪儿都有你)。
到这期位置,HenCoder 的自定义 View 系列的绘制部分就结束了,从下期开始,就要开始布局部分了。按照惯例,官方泄露一点截图吧:
布局部分因为技术的概念比绘制要大得多,因此掌握起来也会难一些,这个各位作好思想准备吧。不过你依然能够相信一点:就像以前的绘制部分同样,虽然有不少人已经尝试过经过看博客、看文档、读源码的方式来学习 Android 的布局(有不少甚至尝试过屡次),最终都以「太难了实在学不会」了结,但只要你跟着我走,几期内容以后,你会发现,一样的技术,只要到 HenCoder 来学,它怎么就变得那么的简单。
就像本文标题和开头我说的,关注我,你就能达到大师级水平,这话我憋了很久,如今终于敢说了。由于,我作到了。