Skip to content

屏幕适配

ZhangPan edited this page Jul 19, 2025 · 8 revisions

一、屏幕适配相关概念

1.dpi的计算公式

dpi = √(宽² + 高²) / 屏幕尺寸

2.density

density表示1dp有多少像素,它的计算公式如下:

density = dpi / 160;

Android早期将160dpi作为“中等密度”的基准,这一数值的选择源于早期主流设备的实际像素密度(如HTC G1的160dpi),同时通过整除关系简化计算:

120dpi(低密度)= 160/1.33

240dpi(高密度)= 160×1.5

320dpi(超高密度)= 160×2 。 以160dpi为基准时,1dp在标准屏幕上等于1px,高于或低于基准密度的屏幕则按比例缩放,确保UI元素在不同设备上显示大小一致

3.dp与px的关系

根据density的含义可以得出px的计算方式:

px = dp * density;

density-independent pixel,是 Android 特有的单位,只与 DPI 有关,保证了在不同屏幕像素密度的设备上显示相同的效果。以 DPI=160 为基准 1dp=1px,用设备实际DPI值/160=density 密度,即 1dp 等于多少 px。用屏幕宽或高的 px/density= 屏幕宽或高最大dp长度。

二、为什么要做屏幕适配

市面上的机型,不同分辨率*不同屏幕尺寸=无限多种DPI组合。

举个例子

  • 一个5英寸的手机,分辨率为1080*1920,根据公式计算出dpi为440,density为2.75,因此这款手机的宽度为1080/2.75=392.73dp
  • 一个5英寸的手机,分辨率为1280*720 ,根据公式计算出dpi为293,density为4.3 ,因此这款手机的宽度为1280/4.3 = 297dp

因此,如果在第二款手机上设置宽度为 297dp,刚好充满屏幕。而如果在第一款手机上则无法充满屏幕。因此可以看出 dp 并不能适配所有屏幕。

三、屏幕适配方案

1. dimen 宽高适配

通过穷举市面上所有 Android 手机的屏幕像素尺寸来实现适配,通过比例换算来为不同分辨率的屏幕分别准备一套 dimens 文件,应用在运行时再去引用和当前设备完全匹配的 dimens 文件,以此来实现屏幕适配。

这一方案最大的确定是容错率低,只有精准匹配分辨率才能适配,否则只能引用默认dimens文件夹,显示效果就会有很大出入。

c4f2ee630a8d5dd7c336693fd20b531d 3f4a56bd10ebdf7834cff6534f0ad3a5

smallestWidth 限定符适配

大部分手机的宽度 dp 值集中在 320-450 之间,大部分 1080P 的手机应该都是 360dp,390dp,411dp。smallestWidth 限定符适配需要在 res 文件夹下创建各种屏幕分辨率对应的 values-swxxxdp 文件夹,如下图:

image

smallestWidth 限定符适配原理与屏幕分辨率限定符适配原理一样,系统都是根据限定符去寻找对应的 dimens.xml 文件。例如程序运行在最小宽度为 360dp 的设备上,系统会自动找到对应的 values-sw360dp 文件夹下的 dimens.xml 文件。如果没有匹配当刚好一样大小的分辨率,则选择相差最小的文件夹下的 dimens.xml。需要注意的是“最小宽度”是不区分方向的,即无论是宽度还是高度,哪一边小就认为哪一边是“最小宽度”。

生成 dimens 文件

根据设计师给的设计稿的宽高计算出屏幕的dp宽度,比如,经计算,设计师给的设计稿的宽度为 375dp 。那么就以 values-sw375dp 为基准,那么就在该目录下添加 dp 值。如下:

    <dimen name="dp_1">1dp</dimen>
    <dimen name="dp_1_5">1.5dp</dimen>
    <dimen name="dp_2">2dp</dimen>
    <dimen name="dp_2_5">2.5dp</dimen>
    <dimen name="dp_3">3dp</dimen>
    <dimen name="dp_4">4dp</dimen>
    <dimen name="dp_4_5">4.50dp</dimen>
    <dimen name="dp_5">5dp</dimen>
    <dimen name="dp_6">6dp</dimen>
    ... 

其它 values 目录则只需根据与 375dp 的比值扩大或者缩小dp值即可。例如,values-sw750dp 下 dp_1 的值应该刚好为 values-sw375dp目录下值的2倍。

当然,这么多文件不需要自己编写。可以通过 As 插件自动生成即可。插件地址: ScreenMatch

今日头条屏幕适配方案原理

今日头条适配方案默认项目中只能以宽作为基准,进行适配。我们根据density的计算公式,以设计稿的宽度作为标准,可得出如下公式:

设计图总宽度(单位为 dp) = 当前设备屏幕总宽度(单位为像素)/ density

上述公式中因为设计稿的宽度是不变的,当前设备屏幕总宽度也是无法改变的,因此只能通过修改density的值来使得等式两边相等。那么可以得出以下公式:

density = 当前设备屏幕总宽度(单位为像素)/ 设计图总宽度(单位为 dp)

在求得density的之后,通过代码来修改系统的density值即可完成适配。

公众号:玩转安卓Dev

Java基础

面向对象与Java基础知识

Java集合框架

JVM

多线程与并发

设计模式

Kotlin

Android

项目相关问题

Android基础知识

Android消息机制

Android Binder

View事件分发机制

Android屏幕刷新机制

View的绘制流程

Activity启动

Framework

性能优化

Jetpack&系统View

第三方框架实现原理

计算机网络

算法

Clone this wiki locally