阅读 351

Android屏幕适配方案

先讲述一些屏幕适配相关概念,然后介绍下3种主要的适配方案以及优缺点。

一.基本概念

1. 像素(px)

  • 像素是手机屏幕的最小构成单元。

2. 分辨率 (px)

  • 手机在横向、纵向上的像素点数总和,一般描述成 宽高 ,即横向像素点个数纵向像素点个数。
  • 例如:1080x1920,即宽度方向上有1080个像素点,在高度方向上有1920个像素点。

3.屏幕尺寸(inch)

  • 手机对角线的物理尺寸,单位 英寸(inch),一英寸大约2.54cm,
  • 例如:常见的尺寸有4.7寸、5寸、5.5寸、6寸

4.屏幕像素密度 (dpi)

  • 每英寸长度上像素点个数。"dot per inch":
  • 例如每英寸内有160个像素点,则其像素密度为160dpi。
以上四者之间关系
  • √((宽px)²+(高px)²)  /  (屏幕尺寸inch) = (屏幕像素密度dpi)

5. dp,dip,sp

  • dip和dp是一个意思,都是Density Independent Pixels的缩写,即密度无关像素。
  • 例如:在Android中,规定以160dpi为基准,1dip=1px,如果密度是320dpi,则1dip=2px,以此类推。
  • android中的dp在渲染前会将dp转为px,计算公式: px = density * dp; density = dpi / 160; px = dp * (dpi / 160);
  • 注意:dp与px不一定都是2倍的关系,与屏幕像素密度dpi有关。

6. hdpi,mdpi,xhdpi,xxhdpi,xxxhdpi

  • 用来修饰Android中的drawable文件夹及values文件夹,用来区分不同像素密度下的图片和dimen值。
  • 在设计图标时,对于五种主流的像素密度(mdpi、hdpi、xhdpi、xxhdpi 和 xxxhdpi)应按照 2:3:4:6:8 的比例进行缩放。

2.适配方案

主要介绍一些适配方案,至于布局编码注意的问题,不详细介绍了。

  • 使用 “wrap_content” 和 “match_parent” 尺寸值而不是硬编码的尺寸,视图就会相应地仅使用自身所需的空间或展开以填满可用空间。
  • weight是线性布局的一个独特的属性,我们可以使用这个属性来按照比例对界面进行分配。
  • 使用相对布局,禁用绝对布局。等等...

适配目的是使得某一元素在Android不同尺寸、不同分辨率的手机上具备相同的显示效果。

1.屏幕分辨率限定符(宽高限定符)

设定一个基准的分辨率,也就是设计图对应的分辨率,其他分辨率都根据这个基准分辨率来计算,在不同的尺寸文件夹内部,根据该尺寸编写对应的dimens文件。

  • 屏幕分辨率限定符适配需要在 res 文件夹下创建各种屏幕分辨率对应的 values-xxx 文件夹。
  • 然后根据一个基准分辨率,例如基准分辨率为 1280x720,将宽度分成 720 份,取值为 1px~720px,将高度分成 1280 份,取值为 1px~1280px,生成各种分辨率对应的 dimens.xml 文件。

基准分辨率 1280x720 对应的dimes文件:

  • 宽度为720,将任何分辨率的宽度整分为720份,取值为x1-x720
  • 高度为1280,将任何分辨率的高度整分为1280份,取值为y1-y1280

那么对于1080*1920的分辨率的dimens文件来说,宽度如下:

  • x1=(1080/720)*1=1.5px
  • x2=(1080/720)*2=3px
    ...
  • x719=(1080/720)*719=1078.5px
  • x720=(1080/720)*720=1080px

如下分别为分辨率 1280x720 与 1920x1080 所对应的横向dimens.xml 文件:

分辨率 1280x720 与 1920x1080 所对应的横向dimens

  • 缺点 这个方案有一个致命的缺陷,那就是需要精准命中才能适配,比如1920x1080的手机就一定要找到1920x1080的限定符,否则就只能用统一的默认的dimens文件了。而使用默认的尺寸的话,UI就很可能变形,简单说,就是容错机制很差。

2. smallestWidth 限定符

smallestWidth适配,或者叫sw限定符适配。指的是Android会识别屏幕可用高度和宽度的最小尺寸的dp值(其实就是手机的宽度值),然后根据识别到的结果去资源文件中寻找对应限定符的文件夹下的资源文件。 smallestWidth 限定符 和宽高限定符适配原理上是一样的,都是系统通过特定的规则来选择对应的文件。

  • smallestWidth 限定符屏幕适配方案 只是把 dimens.xml 文件中的值从 px 换成了 dp,原理和使用方式都是没变的。

分辨率 1280x720 与 1920x1080 所对应的横向dimens

  • smallestWidth 限定符比屏幕分辨率限定符需要少量 dimens.xml 文件
  • smallestWidth 限定符适配采用的单位是 dp 和 sp。屏幕分辨率限定符采用px。
  • 屏幕分辨率限定符需要精准命中才能适配,而 smallestWidth 限定符适配寻找 dimens.xml 文件的原理是从大往小找,即使没有完全匹配也能达到不错的适配效果。
  • 缺点:
  • 侵入性高,在所有地方都需要引用。
  • 还是没有办法覆盖所有的机型分辨率,部分机型可能适配效果还是不佳。
  • 不能以高度为基准进行适配。
  • 生成很多文件,增大APP体积1~2M。

3. 今日头条适配方案

今日头条屏幕适配方案的核心原理在于,动态计算density,通过系统api,将density赋值给系统,抛弃掉系统默认计算density的计算公式。 公式: density = 屏幕宽度px / 设计图宽度(375dp)

  • 使用成本非常低,操作非常简单
  • 侵入性非常低
  • 可适配三方库的控件和系统的控件
  • 缺点
  • 会全局影响APP的控件大小,例如一些第三方库控件,他们设计的时候可能设计图尺寸并不是像我们一样是375dp,这样就会导致控件大小变形等一些问题。 当某个系统控件或三方库控件的设计图尺寸和和我们项目自身的设计图尺寸差距非常大时,这个问题就越严重。

参考:Android屏幕适配方案分析