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

作者: 行者_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