美文网首页
Android屏幕碎片化细节优化

Android屏幕碎片化细节优化

作者: Richard_7df6 | 来源:发表于2018-06-06 21:08 被阅读0次

    先放三张自己做code review的ppt


    2.png
    1.png
    3.png

    从上面的图片上已经知道了大概。

    由于Android碎片化严重,虽然Android官方提供了dp单位来适配,解决了大部分的问题。但是还是有细节问题,这就是今天的内容。

    存在什么问题呢?

    假设我们UI设计图是按屏幕宽度为360dp来设计的,那么在上述设备上,屏幕宽度其实为1080/(440/160)=392.7dp,也就是屏幕是比设计图要宽的。这种情况下, 即使使用dp也是无法在不同设备上显示为同样效果的。 同时还存在部分设备屏幕宽度不足360dp,这时就会导致按360dp宽度来开发实际显示不全的情况。

    而且上述屏幕尺寸、分辨率和像素密度的关系,很多设备并没有按此规则来实现, 因此dpi的值非常乱,没有规律可循,从而导致使用dp适配效果差强人意。

    解决方法

    从上图中可以看出,android最终的尺寸单位还是转为px进行布局的。px = density * dp;

    既然dpi(屏幕像素密度)不能改变,dp也是在代码中写死。那只能改变density了。

    通过阅读源码,我们可以得知,density 是 DisplayMetrics 中的成员变量,而 DisplayMetrics 实例通过 Resources#getDisplayMetrics 可以获得,而Resouces通过Activity或者Application的Context获得。

    先来熟悉下 DisplayMetrics 中和适配相关的几个变量:

    1.DisplayMetrics#density 就是上述的density
    
    2.DisplayMetrics#densityDpi 就是上述的dpi
    
    3.DisplayMetrics#scaledDensity 字体的缩放因子,正常情况下和density相等,但是调节系统字体大小后会改变这个值
    
    /**
         * 设置activity页面 density
         * @param activity
         * @param application
         */
        public static void setCustomDensity(Activity activity, final Application application){
            final DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();
    
            if(sNoncompatDesity == 0){
                sNoncompatDesity = appDisplayMetrics.density;
                sNoncompatScaledDensity = appDisplayMetrics.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() {
    
                    }
                });
            }
            final float targetDensity = appDisplayMetrics.widthPixels / 360;
            final float targetScaledDensity = targetDensity * (sNoncompatScaledDensity / sNoncompatDesity);
            final int targetDensityDpi = (int)(160 * targetDensity);
    
    
            appDisplayMetrics.density = targetDensity;
            appDisplayMetrics.scaledDensity = targetScaledDensity;
            appDisplayMetrics.densityDpi = targetDensityDpi;
    
            final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
            activityDisplayMetrics.density = targetDensity;
            activityDisplayMetrics.scaledDensity = targetScaledDensity;
            activityDisplayMetrics.densityDpi = targetDensityDpi;
        }
    

    只要在oncreate中调用下,即可解决分析的问题,有没有调用私有api,简单,不需要改动之前代码。

    还是不错的。

    相关文章

      网友评论

          本文标题:Android屏幕碎片化细节优化

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