Android之屏幕适配

Posted 一场雪ycx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android之屏幕适配相关的知识,希望对你有一定的参考价值。

前言

android 系统能发展到今天,离不开其开源性,但是随着越来越多的设备接入 Android 系统,并对 Android 系统进行各种各样的定制,导致长期以来出现了各种碎片化严重的问题。例如,Android 屏幕尺寸多种多样,如 5 寸、5.9 寸、6 寸、6.1 寸 等等,当然,屏幕分辨率也是多种多样,这很容易导致同一元素在不同手机上显示的效果不同的问题,因此,Android 应用开发中的屏幕适配工作也越来越重要。

本篇文章就介绍一下 Android 中屏幕适配相关的知识。

屏幕适配基本概念

屏幕尺寸

屏幕尺寸是指手机对角线的物理长度,单位是 英寸(inch,1 inch = 2.54 cm),

例如我们常见的 6 英寸手机,表示手机的对角线长度是 6 * 2.54 = 15.24 cm 。

屏幕分辨率

指的是手机在横向、纵向上的像素点数总和,单位是 px(pixel,1 pixel = 1 像素点) ,

分辨率一般描述成 A * B ,例如:1080 * 1920,表示屏幕每一行有 1080 个像素点,每一列有 1920 个像素点。

对于 Android 设备,我们可以通过 ADB 命令快速查看屏幕分辨率信息:

adb shell wm size

屏幕像素密度

指的是每英寸的像素点数量,单位是 dpi(dots per ich),假设设备内每英寸有160个像素,那么该设备的屏幕像素密度为 160 dpi 。

屏幕像素点的计算公式如下:
屏幕像素密度 = 单行像素点 数 2 + 单列像素点 数 2 屏幕尺寸 屏幕像素密度 = \\frac\\sqrt单行像素点数^2 + 单列像素点数^2屏幕尺寸 屏幕像素密度=屏幕尺寸单行像素点2+单列像素点2
即,先用勾股定理计算出对角上的像素点数量,再用该数量除以屏幕尺寸。

例如:4.7 英寸,1080 * 1920 分辨率的手机,它的像素密度为:
屏幕像素密度 = 108 0 2 + 192 0 2 4.7 ≈ 469 d p i 屏幕像素密度 = \\frac\\sqrt1080^2 + 1920^24.7 ≈ 469 dpi 屏幕像素密度=4.710802+19202 469dpi
对于 Android 设备,我们可以通过 ADB 命令快速查看屏幕像素密度信息:

adb shell wm density

密度无关像素

密度无关像素,英文名 density-independent pixel,单位 dp,它是 Android 特有的单位,它与设备上的实际物理像素点无关,只与屏幕像素密度有关,它可以保证在不同屏幕像素密度的设备上显示相同的效果。

注意:在 Android 中,1 英寸 = 160 dp

为什么要用 dp 而不直接用 px 呢?我们举个简单的例子:

假设需要在屏幕上显示一条长度为屏幕宽度一半的线,用 px 来表示的话,那么:

  • 在分辨率 480 * 800 ,屏幕密度 240 dpi 的设备上(约 3.89 英寸),这条线的长度应该为 240 px
  • 在分辨率 320 * 480 ,屏幕密度 160 dpi 的设备上(约 3.61 英寸),这条线的长度应该为 160 px

对于以上情况,如果使用 px 设置这条线的长度,需要使用两个不同的值才能适配两个不同分辨率的设备

但如果我们使用 dp 为单位,那么在以上这两种情况,都只需要使用 160 dp 就可以将这条线显示为屏幕一半的长度。

在平时的开发中,UI 设计师给我们的设计图都是以 px 为单位的,而我们则是要使用 dp 作为单位进行开发,因此我们需要将 px 转化为 dp,他们之间的转换关系如下所示:

密度类型代表的分辨率(px)屏幕密度(dpi)换算(px/dp)
低密度(ldpi)240 * 3201201 dp = 0.75 px
中密度(mdpi)320 * 4801601 dp = 1 px
高密度(hdpi)480 * 8002401 dp = 1.5 px
超高密度(xhdpi)720 * 12803201 dp = 2 px
超超高密度(xxhdpi)1080 * 19204801 dp = 3 px

由此可见,在设备屏幕密度为 160 dpi 的情况下,1 dp = 1 px 。

独立比例像素

独立比例像素,英文名 scale-independent pixel,单位 sp,它是 Android 特有的单位,在 Android 中一般用于设置字体大小。

一般来说,1 sp = 1dp 。推荐使用偶数 sp 值设置字体大小,不推荐使用奇数和小数,因为容易造成精度的丢失问题。

屏幕适配方案

dp 原生方案

我们需要思考,Android 使用 dp 究竟解决了什么问题?

在上面 dp 概念的介绍中,我们知道,在 Android 中,1 英寸 = 160 dp

对于相同尺寸,不同分辨率的设备,他们拥有着不同的屏幕像素密度,因此他们每 1 dp 所代表的像素数量是不一样的,

如果使用相同的 px 值显示一条线,那么这条线的长度在两个设备上将会显示不同的比例,

如果使用 dp 作为单位,由于每一 dp 它所对应的物理长度是一样的,因此,使用相同的 dp 值,他们的显示的比例是一样的。

实际上,dp 的优势也主要体现在相同尺寸,不同分辨率的设备的适配效果。对于不同尺寸不同分辨率的设备,dp 的适配效果就差强人意了!

举个例子。

假设我们的 UI 设计图是按屏幕分辨率 1080 * 2670,屏幕尺寸为 6 寸的设备(dpi 约为 480)来设计的,则通过计算,UI 图中设备屏幕的最大宽度为 360 dp 。

但是对于屏幕分辨率 1080 * 1920,屏幕尺寸为 5 寸的设备(dpi 约为 440),通过计算,

它的屏幕宽度其实为 1080 / (440/160) = 392.7 dp

也就是屏幕是比设计图要宽的。

这种情况下, 即使使用 dp 也无法在不同设备上显示为同样效果, 同时还存在部分设备屏幕宽度不足 360 dp,这时就会导致按 360 dp 宽度来开发,实际却显示不全的情况。

总结:仅使用 dp 原生方案进行屏幕适配,适配性非常差,不建议使用该方案。

sw 限定符适配方案

sw 限定符适配即 smallestWidth 适配,也叫最小宽度限定符适配。

它的原理是,Android 会识别屏幕可用高度和宽度的最小尺寸的 dp 值,然后根据识别到的结果去 资源文件寻找对应限定符的文件夹下的资源文件。其实就是系统通过特定的规则来选择对应的文件。

举个例子。

某手机的屏幕分辨率是 1080 * 1920,屏幕像素密度是 480 dpi,通过计算,

它的最大宽度对应的 dp 值是:1080 / (480 / 160) = 360 dp

根据这个 360 dp 值,系统会去寻找 value-sw360dp 的文件夹以及对应的资源文件并使用它。

如果没有 value-sw360dp 文件夹,系统会向下寻找,比如离 360 dp 最近的只有 value-sw350dp,那么Android就会选择 value-sw350dp 文件夹下面的资源文件。

一般来说,value-swXXXdp 这些文件夹都会创建在 /src/main/res/ 目录下,例如我工程中创建的 value-sw480dp 文件夹:

在创建这些文件夹前,我们需要提前设置好基准尺寸,一般我们会将 UI 设计图中使用的最大宽度对应的 dp 值来作为基准 dp 值,比如下面我这里将会以 360 dp 作为基准,我们来看看基准资源文件 /src/main/res/value/dimens.xml,如下所示:

接下来,我们创建一个value-sw480dp 文件夹并在其中创建 dimens.xml 文件:

那么这份数据是怎么计算得到的呢,当然也是在基准尺寸的基础上计算得到的,

即:dp_2 = (480 / 基准) x 2 = (480 / 360) x 2 = 2.6667 dp

这种适配方案容错率低,其缺点就是侵入性高,且需要根据不同机型的最大宽度 dp 创建多个文件夹,维护成本也比较大。

相比于使用 dp 原生方案sw 限定符适配方案 显然更加合适。

Android机子屏幕适配最简单最全面方案

调试布局会发现,每款手机显示的布局效果有时候不尽人意,这是因为我们在写代码时,只针对了调试机型屏幕做了设计,而没有考虑到每个手机适配的问题,虽然大家都知道使用dp,但是并没能完全解决问题,而且在美工小伙伴也不会设计dp的图出来给你作为参考。今天就给大家介绍一款适配,来自鸿洋大神之手的工具AutoLayout:https://github.com/hongyangAndroid/AndroidAutoLayout

相信很多同学是知道这个库的,就是不知道怎么使用,什么导入module,什么注明之类的,今天写给大家的方法,绝对最简单,最方便!

在build.gradle添加依赖 compile ‘com.zhy:autolayout:1.4.5‘

在AndroidManifest清单文件中注明你要设计的初始屏幕尺寸

也就是在你的项目的中注明你的设计稿(美工给你的)的尺寸。 最后使用让你的Activity继承AutoLayoutActivity 现在你就可以安心的使用UI设计图了!可以在布局中直接写px,而不用再担心去换算dp的问题了!

以上是关于Android之屏幕适配的主要内容,如果未能解决你的问题,请参考以下文章

Android之屏幕适配方案

Android 屏幕适配扫盲教程

Android-屏幕适配全攻略(绝对详细)(一)

一种非常好用的Android屏幕适配

Android开发系列之屏幕密度和单位转换

Android 启动图适配