首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

QQ的底部Tab栏高斯模糊效果源码解析

前言

前段时间QQ更新后发现下面的Tab栏添加了动态高斯模糊效果,众所周知,高斯模糊这玩意儿比较耗时,动态的模糊效果在安卓的APP中比较少见。在自己猜测了几种做法之后想知道QQ是怎么实现的,于是反编译了一下QQ的apk。

鉴于我的逆向基础门都没入,属于只会用一个jadx查查16进制id这种,这里就不班门弄斧介绍了,感兴趣的可以自己去搜搜类似的文章看看。不过这里不得不说QQ的措施做得真好,它里面的所有控件id,资源id,layout的命名混淆后大部分是name,想通过查找id来寻找代码文件对我来说基本不可能,曾经反编译过网易云音乐的app,它就没有做这项措施,可以轻易的通过工具查找到id后定位到具体的代码文件。下面可以看看最后的效果。

效果

gif图录制时会变糊成一团,下面再附一张图片

废话说完,下面就看看如何做到的吧

1.定位

首先可以知道,这个模糊的效果不是自定义就是拿到具体视图模糊后给当背景,这里可以使用看看这个页面的层级和视图,如下图

图一

可以很清晰的看到在最下面的下面还有个自定义,但是id被混淆成了name,因而定位代码就基本不可能了(仅对我而说)。

2.反编译

既然知道这是个自定义,那么我们就可以试着反编译APK去查找代码了,因为混淆后的自定义view的类名是不会变的。从上图可以看到该View的位于下面,于是试着在这个包名下面寻找一下代码。

这里用最简单的jadx打开QQ的apk后就可以看到QQ混淆后的代码了。几十个包名这里就不上图演示了,鉴于对QQ团队的代码素养的信任,在mobileqq下面直接锁定的widget这个包,然后同样鉴于对QQ团队代码命名素养的信任,我着重寻找类似或者这样的字眼,果然找到了两个文件和

找到后就是苦力活了,因为代码是混淆的,需要把相关的代码倒腾出来再去分析。这里让我最蛋疼的就是这个的代码了。

这里可以看到这个(其实在混淆后这个命名是b,前面的531是jadx软件为了和其他b命名区分自己添加的)既可以是也是方法的int类型,下面还变成了。

花了一个周末的时间对整个代码进行了逻辑分析和重新命名后,后面展示的代码就是根据我自己的理解重新命名的的类和变量名,如果有想看原混淆代码的可以自己去反编译,或者看我上传的一份。

3.代码分析

QQBlurView

先看看这个类的代码,下面代码为了方便查看和理解,是经过我自己的重新命名后的,想看混淆过的源码传送门这边走QQBlurView

这里可以看到在中如果需要模糊效果的话就将模糊的具体操作都交给了,下面还需要注意的点是外界需要传两个进来,一个是本身这个,另一个暂且记做,后面中会用到。

BlurPreDraw

在创建完成后需要注册个监听器,该方法主要作用为:将绘制视图树时执行的回调函数。这时所有的视图都测量完成并确定了框架。客户端可以使用该方法来调整滚动边框,甚至可以在绘制之前请求新的布局。

BlurPreDraw

由于这个页面代码过多,这里就不全部展示了,从前面可以看到,视图注册了监听器,而后调用了的方法

这里说明下,有一些和混淆无关,与其他页面关联的方法这里就删除了,后面也是类似。

从代码中看到先判断从前面传进来的有没有发生变化,就是判断从上次绘制完成后有没有发生改变,对应效果就是,如果QQ中你没有滑动列表,就停止模糊方法,毕竟这是一个耗时耗资源的事,然后就调用模糊最关键的逻辑代码。

上面做了简单的注释,这边做一下总结:

创建一个和模糊区域同等大小的bitmap,将其放在初始化就创建好的canvas中、

获得缩放后取整的宽高和缩放后有些细微变化的比例值

获取和的坐标值,通过相减计算出他们交叉区域的坐标点

获得交叉区域后,将的这一部分内容绘制到上,也就是会知道了前面创建好的上,然后模糊这一在绘制到上就实现了对交叉这一区域的模糊。

下面用简单的图展示一下。

在QQ中,上面的聊天列表就是这个,最下面有一层,上面是透明的tab,实现动态模糊的逻辑就是不断去获取和交叉这一部分区域的视图,将这部分视图模糊后绘制在上,就形成了一种动态模糊的效果。在上面展示的例子中就是这么调用的

QQBlur

最后一个就是模糊调用的线程方法,这里面的还原我其实没有100%的把握,原因前面也说了,这里的命名类型不一样,但是命名却是一模一样的,所以尽我所能去理解并还原了

这段代码最主要的是这一行,调用模糊方法,前面主要是判断模糊方式有没有变化,后面,也是调试参数用的,最后模糊完成后刷新界面,这里的StackBlurManager是一个第三方库,有兴趣的小伙伴可以自己去看一下,QQ做了一些细微的调整,增加了一两个方法。

StackBlurManager

这里默认的模糊方式是JavaBlurProcess,该方法后面还有很多其他模糊方式的方法,应该是在其他情况下供别的地方调用的,感兴趣的朋友可以自己看一下StackBlurManager这个类,这里的是QQ上的,上面那个是第三方框架中的。

ThreadManager和MqqHandler

其实这两个是意外发现的,这是QQ中自己做的线程调度和自定义的handler用法,而且这写方法并没有混淆,有兴趣的话可以观摩学习下代码,我下面贴几行QQ里面这些类的用法。

4.结尾

以上就是这次查找代码的全部收获,全部的代码包括我自己命名的,混淆的原代码,ThreadManager类和StackBlurManager类我都上传到了这里,本意是让大家学习大厂的代码逻辑和思想,如有侵权,第一时间联系我删除,谢谢了。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190828A09RFW00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券