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

本文介绍了如何解析QQ更新后底部Tab栏的动态高斯模糊效果。通过反编译QQ APK,作者定位到相关代码并进行了分析。QQ使用自定义View并在预绘制时模糊指定区域,通过监听视图变化来实现动态模糊效果。文章提供了关键代码片段及思路总结。
摘要由CSDN通过智能技术生成
  • 前言
    前段时间QQ更新后发现下面的Tab栏添加了动态高斯模糊效果,众所周知,高斯模糊这玩意儿比较耗时,动态的模糊效果在安卓的APP中比较少见。在自己猜测了几种做法之后想知道QQ是怎么实现的,于是反编译了一下QQ的apk。
    鉴于我的逆向基础门都没入,属于只会用一个jadx查查16进制id这种,这里就不班门弄斧介绍了,感兴趣的可以自己去搜搜类似的文章看看。不过这里不得不说QQ的措施做得真好,它里面的所有控件id,资源id,layout的命名混淆后大部分是name,想通过查找id来寻找代码文件对我来说基本不可能,曾经反编译过网易云音乐的app,它就没有做这项措施,可以轻易的通过uiautomatorviewer工具查找到id后定位到具体的代码文件。下面可以看看最后的效果。
  • 效果

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

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

1.定位

首先可以知道,这个模糊的效果不是自定义view就是拿到具体视图模糊后给Tab当背景,这里可以使用uiautomatorviewer看看这个页面的层级和视图,如下图
图一
可以很清晰的看到在最下面的TabWidget下面还有个自定义View,但是id被混淆成了name,因而定位代码就基本不可能了(仅对我而说)。

2.反编译

既然知道这是个自定义View,那么我们就可以试着反编译APK去查找代码了,因为混淆后的自定义view的类名是不会变的。从上图可以看到该View的位于com.tencent.mobileqq下面,于是试着在这个包名下面寻找一下代码。
这里用最简单的jadx打开QQ的apk后就可以看到QQ混淆后的代码了。几十个包名这里就不上图演示了,鉴于对QQ团队的代码素养的信任,在mobileqq下面直接锁定的widget这个包,然后同样鉴于对QQ团队代码命名素养的信任,我着重寻找类似blur或者gauss这样的字眼,果然找到了两个文件QQBlurQQBlurView
图二
找到后就是苦力活了,因为代码是混淆的,需要把相关的代码倒腾出来再去分析。这里让我最蛋疼的就是这个QQBlur的代码了。

public  class QQBlur$1 implements Runnable{
private int a = -1;
/* renamed from: a */
final /* synthetic */ StackBlurManager f541a;
final /* synthetic */ azlc this$0;

public QQBlur$1(azlc azlc, StackBlurManager stackBlurManager) {
    this.this$0 = azlc;
    this.f541a = stackBlurManager;
}

public void run() {
    if (!this.this$0.f531b) {
        long elapsedRealtime = SystemClock.elapsedRealtime();
        if (!(this.a == -1 || this.a == azlc.a)) {
            this.this$0.a(this.a, azlc.a);
        }
        this.a = azlc.a;
        int i = azlc.a;
        Bitmap process = this.f541a.process(this.this$0.f531b);
        if (process != null) {
            this.this$0.f519a = process;
        } else {
            QLog.e("QQBlur", 1, "run: outBitmap is null. OOM ?");
        }
        long elapsedRealtime2 = SystemClock.elapsedRealtime();
        this.this$0.f531b;
        this.this$0.f = (elapsedRealtime2 - elapsedRealtime) + this.this$0.f;
        View a = this.this$0.f531b;
        if (a != null && this.this$0.f) {
            a.postInvalidate();
        }
    }
}

这里可以看到这个f531b(其实在混淆后这个命名是b,前面的531是jadx软件为了和其他b命名区分自己添加的)既可以是boolean也是process方法的int类型,下面还变成了View
花了一个周末的时间对整个代码进行了逻辑分析和重新命名后,后面展示的代码就是根据我自己的理解重新命名的的类和变量名,如果有想看原混淆代码的可以自己去反编译,或者看我上传的一份。

3.代码分析

  • QQBlurView

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

@TargetApi(19)
public class QQBlurView extends View {
    //因为这个模糊效果只支持19以上,所以这个drawable是低于19的情况下显示的tab背景
    private Drawable mDefaultDrawable;

    private BlurPreDraw mBlurPreDraw = new BlurPreDraw(this);

    public QQBlurManager mManager = new QQBlurManager();

    private boolean mEnableBlur = true;
    ......

    protected void onDraw(Can
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值