美文网首页
Android - 头条方案屏幕适配笔记

Android - 头条方案屏幕适配笔记

作者: xlq | 来源:发表于2020-06-08 09:50 被阅读0次

    问题背景

    例如设计图宽度为375dp,一个控件的宽度给的是200dp,在设计图上占了200 / 375 = 53%的宽度。

    我们部分手机是这样的, 屏幕宽度为1080px,density是3,如果我们不做适配,直接在xml中填上200dp,那么屏幕宽度占比就是 :(200*3)/ 1080 = 56%,并没有做到等比例缩放。

    在某些手机和设计图的分辨率差别更大的情况下,效果差别就更大。

    抓住问题点:等比例缩放

    要想做到等比例缩放,需要满足一个等式:
    定义:控件宽度 = viewW ,屏幕宽度 = screenW;

    200dp / 375dp = viewW / screenW
    

    我们都以dp作为单位去设计xml,那么

    screenW = 1080px / density
    

    即:

    200dp / 375dp = viewW / (1080px / density)
    

    因为viewW控件宽度固定200dp,屏幕宽度固定1080px,想要等式成立,就必须修改density,这就是头条的适配方案。通过全局修改density的值,来做到等比例缩放。可以看到下面等式:

    density = 1080 /375
    

    上代码

    在Activity的onCreate方法中,setContentView()方法之前调用,项目中可以写一个基类Activity,统一调用。

    object ScreenMatchTool {
    
        private var mOriginDensity = 0 // 原始density
        private var mOriginScaleDensity = 0f // 原始文字缩放density
    
        fun setCustomDensity(activity: Activity,application: Application) {
    
            val applicationMetrics : DisplayMetrics = application.resources.displayMetrics
            mOriginDensity = applicationMetrics.densityDpi
            mOriginScaleDensity = applicationMetrics.scaledDensity
    
            application.registerComponentCallbacks(object : ComponentCallbacks{
                override fun onLowMemory() {
                }
    
                override fun onConfigurationChanged(newConfig: Configuration) {
                    // 用于监听系统修改文字大小
                    if (newConfig.fontScale > 0) {
                        mOriginScaleDensity = application.resources.displayMetrics.scaledDensity
                    }
                }
            })
            /**
             *  假如设计图是iPhone6s的尺寸为标准,分辨率:`750 x 1334 `,ppi:326 (网上可查)
             *  那么density = 326 / 160 = 2, 实际宽度 = 750px / density = 375dp
             */
            val targetDensity = applicationMetrics.scaledDensity / 375 // 修改后的density
            val targetScaleDensity = targetDensity * (mOriginScaleDensity / mOriginDensity) // 修改后的文字缩放density
            val targetDensityDpi = (targetDensity * 160).toInt() // 修改后的屏幕dpi
    
            applicationMetrics.density = targetDensity
            applicationMetrics.scaledDensity = targetScaleDensity
            applicationMetrics.densityDpi = targetDensityDpi
    
            val activityMetrics : DisplayMetrics = activity.resources.displayMetrics
            activityMetrics.density = targetDensity
            activityMetrics.scaledDensity = targetScaleDensity
            activityMetrics.densityDpi = targetDensityDpi
        }
    }
    

    做好适配之后,就可以直接将UI设计图中的dp值写进xml文件中,如果设计图给的是px(本人公司就是),需要做一个数学转换,将px转为dp,然后写入xml文件中。

    转换方法:

    1. 需要知道设计图的标准,分辨率和屏幕ppi,或者和UI沟通是以什么机型为标准做的,分辨率和ppi网上均可查。
    2. density = ppi / 160;
    3. dp = px / density;

    对于老项目来说,去用此方案适配,迁移量还是挺大的。如果是新项目完全可以使用,毕竟大公司方案,质量还是有保障的

    相关文章

      网友评论

          本文标题:Android - 头条方案屏幕适配笔记

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