← Back to list

Android App 屏幕适配

Published on: | Views: 102

android支持的设备很多,屏幕大小各不一样,要用同一个APP在不同的设备上运行,就要让UI在这些设备上合理地显示,一般需要缩放字体大小和UI的宽高等,也可以在不同大小的屏幕上显示不同的布局。在做屏幕适配之前,需要了解一些专业词语。

专业词语

Pixel (像素)

In digital imaging, a pixel, pel,[1] dots, or picture element[2] is a physical point in a raster image, or the smallest addressable element in an all points addressable display device; so it is the smallest controllable element of a picture represented on the screen. 这是wiki的定义,大意是在数字图片中,一个像素是一幅光栅图片中的一个物理点,或者是所有点寻址显示设备上的最小可寻址单元。像素的单位一般是px。

Screen size(屏幕大小)

屏幕的物理大小,是指屏幕对角线的长度(一般用英寸表示,比如5.0inch,6.0inch)。android大致将屏幕划分为small,normal,large,extra-large几个级别: 这里写图片描述

Screen density(屏幕密度)

The quantity of pixels within a physical area of the screen; usually referred to as dpi (dots per inch). 屏幕一块物理区域内像素的数量(ppi),通常也指dpi(dots per inch)。android将屏幕密度大致划分为六个级别: 这里写图片描述 |屏幕密度|衡 量 值| |------|---------| |ldpi (low)|120dpi| |mdpi (medium)|160dpi| |hdpi (high) |240dpi| |xhdpi (extra-high)|320dpi| |xxhdpi (extra-extra-high) |480dpi| |xxxhdpi (extra-extra-extra-high)|640dpi|

Orientation(屏幕方向)

用户视角的屏幕方向,通常为横屏(landscape)和竖屏(portrait),需要注意的是屏幕方向在运行时可以发生变化。

Resolution(分辨率)

整个屏幕的物理像素数量,例如:720x1280,表示屏幕宽度上有720个像素,屏幕高度上有1280个像素。屏幕分辨率和屏幕密度的关系是 这里写图片描述 但通常来说,使用此公式计算出来的结果和代码中返回的结果不一致,据我猜测应该是厂商返回的dpi是有修改的,并不是实际的DPI,这点暂时没有验证。

Density-independent pixel(dp,设备独立像素密度)

用于定义UI布局的虚拟像素单位,dp定义的尺寸和屏幕密度无关,dp是一个物理尺寸(和inch类似),比如50dp在160dpi的设备和240dpi的设备上显示尺寸是一样的。它的基准值是屏幕密度为160dpi的像素,也就是说在160dpi的设备上,50dp和50px的长度一样,而在240dpi的设备上,50dp和75px的长度一样,换算公式如下: px=dp(dpi/160) 从上式可以推出:px/inch=dpi==>px=dppx/(inch160)==>dp=inch160 也就是说,1dp的长度为1/160英寸。

屏幕适配方法(支持3.2及以上)

屏幕适配,首先要明确适配的目标,根据目标屏幕大小决定是否需要做不同的适配。主要的适配方法如下:

  • 图片适配 跟据屏幕密度(dpi)不同,将不同的图片放到合适的目录,比如drawable-mdpi,drawable-hdpi等。
  • 布局和字体适配
    1. xml中尽量使用比例布局layout_weight、wrap_content或者match_parent,使用指定大小时一定要用dp为单位,并且全部定义到dimens文件中;
    2. 使用getResources().getDisplayMetrics()获得屏幕基本信息,计算出最小宽度的dp值,用来区分不同大小的屏幕,对每个不同的屏幕创建values-swdp目录,在这些目录中定义相关的dimens文件;
    3. 字体大小全部使用sp,并且全部定义到dimens文件中。

示例: APP有两个设备需要适配: A设备: DisplayMetrics{density=2.0, width=720, height=1280, scaledDensity=2.0, xdpi=320.0, ydpi=320.0}

B设备: DisplayMetrics{density=1.5, width=720, height=1280, scaledDensity=1.5, xdpi=160.421, ydpi=160.157}

  • 处理图片资源: 上面可以看出A设备对应的图片目录为drawable-xhdpi,而B设备对应的图片目录为drawable-mdpi,图片的大小比例是2:1,先把处理好的图片资源放到各自的目录。
  • 计算它们的dp大小: A设备的大小为: 720/2.0x1280/2.0=360dpx640dp,sw为360dp B设备大小为:720/1.5x1280/1.5=480dpx853dp,sw为480dp 显然B设备要大一些,所以,我们可以将A设备的dimens文件放置到默认目录,然后创建values-sw480dp目录来保存B设备的dimens文件。对于dimens中的值,我们可以按等比缩放来设置,比如A设备中16sp大小的字,在B设备中等比缩放后应该是16*480/360=21.3约为22sp。 注意:swdp的方式,仅支持3.2及以上设备,在以前的设备上可以用分辨率和屏幕大小来设置dimens目录。

参考文章: Supporting Multiple Screens https://en.wikipedia.org/wiki/Pixel https://en.wikipedia.org/wiki/Pixel_density