自定义view - 仿即刻app点赞

作为忠实粉,先丢个凯哥的广告。HenCoder
凯哥更有名的名字应该叫扔物线

HenCoder真的是很良心的作品,拜服。

本项目github:LikeViewDemo

1. 准备工作

1.1 tips

这篇文章是为响应henCoder第一期学习的末期活动——仿写酷UI而写。很遗憾,由于工作原因,当时没有写完,没有参加。后来写完之后,活动结果已经出来了,看了即刻app的Android组大佬精辟的点评之后,我又去重写了一遍代码。周期拖的太长了,还是先把这篇回顾写出来,请网上的各位大佬指教一下,顺便假如凯哥有时间,我也希望能投过去,交交作业。

1.2 效果对比

即刻app原效果:

仿写效果:


自我点评:
没有对比就没有伤害。不放在一起,觉得自己还算达到了效果,但是放在一起,发现还是有一些细节没有处理到位的。

  1. 字体颜色、字体大小
  2. 点赞和发光最后会弹一下,比较平滑。而我仅仅用了BounceInterpolator来处理,效果还是不符合,我认为这个应该需要自定义Interpolator来做到,而我恰好没做。
  3. 仔细一看,发现数字变化的时候,其实还有间距、字体大小的变化。(即刻app上效果可能没有凯哥这张图这么明显,写回顾的时候才发现被我忽略了)

1.3 获取资源

下载一个即刻app,没错。即刻
下载了apk之后,安装起来玩一玩,还蛮有意思的。
玩好之后,就把apk反编译了,apktool可以,直接解压一下也ok,到\res\drawable-hdpi-v4文件夹下,找到我们需要的资源:

作为没有玩过自定义的人来说,这个时候就想的有点多。比如“诶?三个png?这怎么玩呢?到底动画是在view上呢?还是drawable动画呢?”
最后动画做在onDraw()绘制里面。

1.4 点赞接口

即刻的大佬的点评非常精辟,非常详细。看了之后觉得大佬做事非常认真严谨。

于是我也借鉴了一点里面的思想:把点赞抽象为接口,这样,假如需要更多的点赞自定义view,继承接口去实现会更好。


我没考虑假如可以重复点赞的情况。

用接口的一个好处:


把点赞相关都放在布局里面,通过布局的点击事件来统一触发点赞效果。

2. 自定义点赞view

2.1 资源导入

2.2 动画分析


仔细看原效果,左边的View涉及了3张图片。
每次点击,前一个图片缩小退出,后一个图片放大进入。而点赞+发光两张图片的进入动画略有不同。总结如下:

  • 退出动画,时间较短。
    灰拇指和红拇指和发光都可以用
  • 灰拇指进入动画
  • 红拇指进入动画
    该动画最后有个回弹抖动,所以和灰拇指区别开来
  • 发光进入动画

退出动画都是匀速,灰拇指进入也是匀速,红拇指进入会抖动,发光是扩散放大。这样分成4个动画。

基于以上的分析,new出4个ObjectAnimator对象,并有4个对应的类成员变量对应动画进度。


自定义属性使用ObjectAnimator动画的要点是:写好自定义属性的set、get方法。

Alt + insert Android studio快捷键可以快捷完成这一步

2.3 动画顺序

点赞:灰拇指缩小退出,红拇指和发光一同进入
取消点赞:红拇指和发光一同退出,灰拇指进入

可以用AnimatorSet来组合动画播放

2.4 结合点赞事件

还记得我们的Like接口吗?

这里参考了即刻大佬的点评,加入了取消动画的逻辑。

动画进行中更新UI
动画的实际是,执行到每一帧,就去触发重新绘制。


发光动画认为和红拇指进入动画时间差不多,所以不加监听。


动画进行时,重绘。

2.5 自定义View的尺寸

开始绘制之前需要知道绘制区域的尺寸大小,还需要比如适配wrap_content,这是一个比较重要的事情。《Android开发艺术探索》任玉刚大佬总结得特别好,套用一下套路。




默认尺寸还是用dp最好。

2.6 具体绘制

因为涉及点赞、取消点赞的退出进入的动画效果,期间还要调整图片绘制的位置、动画缩放的大小程度等等。所以需要声明一些变量来存储一些可能需要变动的值。


我写的比较乱,待会用到了再来看看注释即可。
首先,需要知道可用于绘制的宽和高。


算出绘制中心能比较省事。而这个边长squareSideLen,我觉得图片部分绘制使用正方形是最合适的,因为不希望非正方形绘制区域导致出现拉伸的情况。所以取可绘制区域中心的一个正方形来进行绘制。

图片在绘制时,发光和拇指没有重叠,所以要把拇指往下移动一点,发光往上移动一点。而拇指在缩小的时候,假如发光不往下移动,会感觉二者不是一个整体。


退出动画进行过程
红灰拇指大小都是一样的,所以只需要写一次rect的位置计算。绘制中心减去边长的一半就是left和top,绘制中心加上边长的一半就是right和bottom。其中,拇指往下稍稍移动,让出发光的位置,所以都加上thumbsOffsetY
其中thumbsScale是拇指部分占可绘制正方形的比例,minifyScale是拇指缩小动画最大缩小的比例。
计算好绘制拇指的rect,就按liked的值进行绘制。

退出动画,画好了拇指,再来画发光:


点赞进入动画
进入动画在退出动画之后,也就是outProgress<1的时候,所以直接加一个return,让进入动画的逻辑比较整洁。

进入动画的拇指部分。1-likeInProgress,这个值会慢慢变小,所以缩小部分会慢慢变小,也就是图形慢慢变大,达到放大的效果。



进入动画的发光部分,这是一个小小的特殊的地方。仔细看效果,发光其实是扩散出去的。



所以这里我觉得用裁剪画布会比较完美。把发光部分单独拎出来画,然后画布以发光每条线指着的中心为圆心画圆裁剪,半径慢慢变大。这样一点点把发光原图呈现出来,就达到了原图的效果。
裁剪接口里面并不支持圆的裁剪,所以使用path路径裁剪,如下addCircle,我发现path在addCircle之后,需要清空一次,然后再来addCircle,保持整洁。

一圈淡红色的扩散效果
仔细看,会发现原效果里面有一个圆形放大的扩散。看上面那张,这里不重复再贴原效果图。画圆裁剪都做了,这个也难不倒。
找好中心,设置好半径,调整一下,也能达到效果。


取消点赞进入效果
拇指部分和点赞进入的红拇指差不多,progress换了一下而已。

这里还有一个小重点,不过是我猜的。原图的发光在退出时,似乎会稍稍顿一下。为达到这个效果,在灰拇指进入时,进度0.1以前,我们还是绘制一下发光效果。绘制了之后,发现效果不错。

到这里,图片部分就绘制完成了。可以在手机上调试一下,对比一下,诶?效果还可以。

3. 绘制点赞数量部分

参考即刻大佬的点评,把图片和数字部分分离,所以单独写了一个数字部分的自定义。

3.1 自定义属性

本来想要继承TextView,这样padding什么的都不用考虑。但是想了想,onDraw全被我重写了,gravity我估计不好处理。于是还是继承View来写。
继承View的话,就需要添加自定义属性了,比如TextSize、TextColor这样的属性等等。
这是attrs.xml里面的属性:



然后我们在构造器里面获取到值,并使用起来。


3.2 尺寸问题

尺寸会比图片要特殊,因为数字可能会比较大,可能有几万个赞。所以把默认大小设置成6位数字,那100万个赞应该是比较难达到了吧。

其实百万个赞没准就达到了,这里算我没适配好。小伙伴看了文章之后有兴趣可以试试。我写完这个回顾,也会找时间去完善起来。

这里也还有个小技巧,mPaint是画笔,上面初始化的时候我们把textSize属性设置给了画笔。这里就可以用画笔来告诉我们一个数字的横向大小是多少。mPaint.measureText("0")

3.3 点赞数量分析

开始绘制之前,还有一些逻辑需要处理。数字需要一个或者两个或者3个的一起执行动画,所以像TextView那也直接setText肯定达不到效果。需要一个一个数字绘制。所以要把点赞数量每一位都保存起来。而且把上一次这一次的都保存起来。


诶?这里我居然用了11位数组,默认又使用6位大小,算我不攻自破了。
这里我还声明了前后点赞数目的位数,什么用后文揭晓。



这个是分析方法,Math.pow()是几次幂的意思。这个方法就把新旧点赞数量放到新旧数组里面去了。

3.4 和点赞事件关联



经过图片的动画,这次的动画简直so easy,所以只贴个代码。

3.5 数字的具体绘制

首先还是绘制区域大小,以及一个数字的宽度。(因为绘制一个数字就得右移一下再绘制下一个数字)


分两种情况讨论,前后点赞位数不一样时。点赞位数不一样,那就得整个数字一起动画出去,新的动画进来。所以这比较特殊。



接下来就是另一种情况:前后点赞位数相同,只是其中的数字不一样。这种情况,其实变化部分的位数也是一样的。比如199+1=200,变化是3位;1988+1=1989;变化是1位。所以从左往右,只要不一样的,就执行动画就ok。


4. 大功告成


数字里面有设置具体多少点赞的方法,加一个数字,调试起来看看,nice!


其实参与活动的一些大佬的项目我还没有去拜读。我希望自己写完后再去借鉴。借鉴完没准能知道大佬的奇思妙想。

第一次写个自定义View的回顾文章。里面涉及到的知识点其实我没讲,只是贴出代码告诉大家我用了啥用了啥。但是具体怎么用,看henCoder 追代码看注释看源码 happy,都是非常好的。

简书的代码高亮比较丑,所以贴出来的都是截图。希望看源码的请移步github。
github:LikeViewDemo

最后,见笑了各位。希望大佬指点一下,希望觉得写得还行的小伙伴点个赞。happy

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,413评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 做一个计算器了,在命令行下接收输入,像1+2 ,然后输出结果,涵盖加减乘除,指数运算。 整数:integer,就是...
    TianAff阅读 280评论 2 3
  • #幸福是需要修出来的~每天进步1%~幸福实修08班~8唐洁-富阳# 20170820(63/99) 【幸福三朵玫瑰...
    你谢谢阅读 239评论 0 1
  • 多數人面對生命挑戰來臨時,習於平面式點對點的思考路徑,於是我們就會碰上各種的該不該,該不該換工作、該不該分手...
    Xuanmany小牡羊阅读 284评论 3 3