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

2020-06-08  本文已影响0人  xlq

问题背景

例如设计图宽度为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;

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

上一篇下一篇

猜你喜欢

热点阅读