关于今日头条适配方案需要注意的

作者: 行者_zm | 来源:发表于2019-01-09 07:45 被阅读18次

今日头条:一种极低成本的Android屏幕适配方式
https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA

自从看了今日头条的适配方案,就被这种容易操作,成本低廉的方案所吸引,大厂出品果然都是精品,大厂的开发在钻研技术上果然不是吹的。
下面说下第一次使用今日头条的方案,感受:

刚开始看到代码,方案理论,确实很好,++是以更改屏幕密度为核心++,直接把代码全部复制下来,放到测试项目中试用今日头条的方法代码

// 系统的Density
 private static float sNoncompatDensity;
 // 系统的ScaledDensity
 private static float sNoncompatScaledDensity;

 public static void setCustomDensity(Activity activity, Application application) {
        DisplayMetrics displayMetrics = application.getResources().getDisplayMetrics();
        if (sNoncompatDensity == 0) {
            sNoncompatDensity = displayMetrics.density;
            sNoncompatScaledDensity = displayMetrics.scaledDensity;
            // 监听在系统设置中切换字体
            application.registerComponentCallbacks(new ComponentCallbacks() {
                @Override
                public void onConfigurationChanged(Configuration newConfig) {
                    if (newConfig != null && newConfig.fontScale > 0) {
                        sNoncompatScaledDensity=application.getResources().getDisplayMetrics().scaledDensity;
                    }
                }

                @Override
                public void onLowMemory() {

                }
            });
        }
        // 此处以360dp的设计图作为例子
        float targetDensity=displayMetrics.widthPixels/360;
        float targetScaledDensity=targetDensity*(sNoncompatScaledDensity/sNoncompatDensity);
        int targetDensityDpi= (int) (160 * targetDensity);
        displayMetrics.density = targetDensity;
        displayMetrics.scaledDensity = targetScaledDensity;
        displayMetrics.densityDpi = targetDensityDpi;

        DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
        activityDisplayMetrics.density = targetDensity;
        activityDisplayMetrics.scaledDensity = targetScaledDensity;
        activityDisplayMetrics.densityDpi = targetDensityDpi;
    }


以上是今日头条的代码;
看到方法的参数和里面的内容,我就在想为啥同时使用Activity和Application

setCustomDensity(Activity activity, Application application)

其实可以直接使用Application,不必使用Activity啊,为啥要用两个呢?

然后我就试着只使用Application,抛弃了activity这个参数。

因为这样不必每一个activity中都要调用这个方法了,直接继承Application,写在里面就好了,想想的很美好的样子

上手开始run()代码;

发现方案并没有起作用,这让我百思不得其解,然后又重新回到了今日头条方案上,通过各种查资料发现:

Application中只能获取屏幕的density,scaledDensity,densityDpi,并不能修改,或者说修改了并不生效。

那好吧,今日头条的方法果然必须是这样的,没有多余,没有缺少,果然牛逼
然后我就封装了一个activity类,测试使用继承这个类,不必在每个activity中都调用一次这样的方法了。

然后我开始run()代码,果然很牛逼第一个手机试验成功,紧接着把手上的测试机全部试验一下,果然很完美,正在我开心的时候,测试机上收到其他APP的推送消息,我点了一下,调整到其他APP,然后我看完,回来准备接着享受这种低成本的适配方案时,发现刚刚适配的方案失效了,what?这是什么原因?

请注意:我刚刚是从适配的的demo跳转到了其他的APP,然后又回到了demo

通过多次尝试,试验发现适配方法只在调用布局之前更改了该activity的密度,更改完并不是一直更改,而是在onResume()后使用了系统的密度,而我没有在onResume()方法中添加所以导致了这个情况。

原来,在activity中除了要添加在onCreate中布局创建之前,还要在onResume()方法中添加一下

这些调整完,我紧接着想到了,弹出对话框,以及Toast等等这些,因为弹出对话框需要适配,Toast并不需要适配,但是我调整了字体大小,会不会影响到Toast;带着这些疑问,我就又开始探索了;

发现在使用Application的对象调用时Toast的字体大小正常,而弹出框的size就不行了不适配了,原因也很简单,上述说的,只在activity中适配了

使用activity的对象调用Toast时,字体大小发生了不适配,而弹出框就正常

由此发现Toast不能再activity中对象使用,不然会影响字体的,所以我直接封装了一个Toast使用Application的对象。对于弹出对话框,其实一般不怎么使用Application,只要不使用Application对象没啥问题的。

差不多到这,基本上没啥大问题了,项目中基本上都可以通用了。

最后:

1.Application中只能获取屏幕的density,scaledDensity,densityDpi,并不能修改,或者说修改了并不生效,需要在activity调用

2.在activity中除了要添加在onCreate中布局创建之前,还要在onResume()方法中添加一下

3.由此发现Toast不能再activity中对象使用,不然会影响字体的,所以我直接封装了一个Toast使用Application的对象。

4.对于弹出对话框,其实一般不怎么使用Application,只要不使用Application对象没啥问题的

相关文章

网友评论

    本文标题:关于今日头条适配方案需要注意的

    本文链接:https://www.haomeiwen.com/subject/bqfbrqtx.html