Android 屏幕适配

发布于 2024-08-22 23:23:30 字数 4614 浏览 13 评论 0

众所周知,Android 机型尺寸各种各样,于是屏幕适配就成了 Android 开发中很重要的一环。Android 屏幕适配可能一些开发者都会遇到这样的问题,今天就来分享下屏幕适配,你会发现其实 Android 屏幕适配也可以很简单。

基本概念

Android 屏幕适配必须要理解的一些概念,这部分可能比较枯燥,但是俗话说的好“工欲善其事,必先利器”,翻译过来就是“有什么样的枪,决定你打什么样的鸟”,一旦这些概念你理解掌握了,屏幕适配你自然而然就觉得简单多了。

px

是英文单词 pixel 的缩写,意为像素,屏幕上的点。我们通常所说的分辨率如 480X800 就是指的像素。

在设计领域中,像素是用来计算数码影像的最小单位。计算机中显示的图像并非连续的线条组成,而是由许多肉眼看不见的小点组成。如果把影像放大数倍, 会发现这些连续色调其实是由许多色彩相近的小点所组成,这些小点就是构成影像的最小单位“像素”。由于是最小的独立显示单位,px 均为整数,不会出现 0.5px 的情况。如:

看这个色彩鲜艳的 LED 灯(原图大小)

你能想象这才是他的本来面目吗?(放大之后)

in

表示英寸,是屏幕的物理尺寸。每英寸等于 2.54 厘米。例如我们经常说的手机屏幕大小有,5(英)寸、4(英)寸就是指这个单位。这些尺寸是屏幕的对角线长度。如果手机的屏幕是 4 英寸,表示手机的屏幕(可视区域)对角线长度是 4 X 2.54 = 10.16 厘米。

dpi

dpi 是 Dots Per Inch 的缩写, 每英寸点数,即每英寸包含像素个数。比如 320X480 分辨率的手机,宽 2 英寸,高 3 英寸, 每英寸包含的像素点的数量为 320/2=160dpi(横向)或 480/3=160dpi(纵向),160 就是这部手机的 dpi,横向和纵向的这个值都是 相同的,原因是大部分手机屏幕使用正方形的像素点。

density

屏幕密度,density 和 dpi 的关系为 density = dpi/160

dp

也即 dip,设备独立像素,device independent pixels 的缩写,Android 特有的单位,在屏幕密度 dpi = 160 屏幕上,1dp = 1px。

sp

和 dp 很类似,一般用来设置字体大小,和 dp 的区别是它可以根据用户的字体大小偏好来缩放。

Android Drawable

我们新建一个 Android 项目后应该可以看到很多 drawable 文件夹,分别对应不同的 dpi

  • drawable-ldpi (dpi=120, density=0.75)
  • drawable-mdpi (dpi=160, density=1)
  • drawable-hdpi (dpi=240, density=1.5)
  • drawable-xhdpi (dpi=320, density=2)
  • drawable-xxhdpi (dpi=480, density=3)

市面上的一些 Android 教程大多都是教的是为每种 dpi 都出一套图片资源,这个固然是一种解决办法,但同时也是一种非常笨的方法,为美工或者设 计增加了不少的工作量不说,同时也会让你的 apk 包变的很大。那么有没有什么好的方法既能保证屏幕适配,又可以最小占用设计资源,同时最好又只使用一套 dpi 的图片资源呢?下面就来讲解下项目中总结出来的这个方法。

首先必须清楚一个自动渲染的概念,Android SDK 会自动屏幕尺寸选择对应的资源文件进行渲染,如 SDK 检测到你手机 dpi 是 160 的话会优先到 drawable-mdpi 文件夹下找对应的图片资 源,注意只是优先,假设你手机 dpi 是 160,但是你只在 xhpdi 文件夹下有对应的图片资源文件,程序一样可以正常运行。所以理论上来说只需要提供一种 规格的图片资源就 ok 了,如果只提供 ldpi 规格的图片,对于大分辨率的手机如果把图片放大就会不清晰,所以需要提供一套你需要支持的最大 dpi 的图片, 这样即使用户的手机分辨率很小,这样图片缩小依然很清晰。

xhdpi 成为首选

上面说了只需要提供一套大的 dpi 的图片就 ok 了,现在市面手机分辨率最大可达到 1080X1920 的分辨率,如 Nexus5,dpi 属于 xxhdpi,但是毕竟还没普及,目前市面上最普遍的高端机的分辨率还多集中在 720X1080 范围,也就是多集中在 xhdpi,所以目前来看 xhpdi 规格的图片成为了首选。当然随着技术规格的提高以后发展,以后可能市场上 xxdpi 的手机会越来越普遍,但这是后话。

设计资源紧张怎么办?

在现在的 App 开发中,基本都会有 iOS 和 Android 版本,有些公司为了保持 App 不同版本的体验交互一致,还有些公司的设计资源可能比较紧 张,这些情况下 iOS 和 Android 版本基本是一个设计师主导,而大多数情况下设计师可能更会以 iPhone 手机为基础进行设计,包括后期的切图之类 的。这个时候身为 Android 开发人员你是否还要求设计师单独为 Android 端切一套图片资源呢?这会让你们的设计师崩溃的,下面就来告诉一个项目中 总结的更棒的方法。

相信设计师们一般都会用最新的 iPhone5(5s 和 5 的尺寸以及分辨率都一样)来做原型设计,而 iPhone5 的屏幕分辨率为 640X1164, 屏幕尺寸为 4 英寸,根据勾股定理(a^2 + b^2 = c2)6402+1164^2=1764496, 然后再对其开根号可求出屏幕对角线的分辨率为:1328,除以 4 可得出 iphone5 的 dpi:1328/4≈332
可以看出 iPhone5 的屏幕的 dpi 约等于 320, 刚好属于 xhdpi,所以你可以很自豪的像你们的设计师说不用专门为 Android 端切图,直接把 iPhone 的那一套切好的图片资源放入 drawable-xhdpi 文件夹里就 ok 了。

wrap_content VS dp

wrap_content 和 dp 都是在 Android 开发中应该经常用到的,然后它们冥冥中是有关系的。

假设你看了这篇文章后都是统一有 xhdpi 的资源,那么你用 wrap_content 完全没有问题,Android 会自动为其他规格的 dpi 屏幕适 配,比如你在 xhdpi 放了一张 120X120px 大小的图片,那么在在 hdpi 屏幕上显示的就只有 120/2*1.5=90px 大小,但是如果你不小心 同样把这张图片也放入了 mdpi 了,这个时候用 wrap_content 显示就会有问题,具体看下面的例子:

例如假设你只在 drawable_xhdpi 文件夹下放了 test 图片,xhdpi 的设备会去 xhdpi 文件夹下找到 test 图片并直接显示,而 mdpi 的设备优先会去 mdpi 文件夹里查找 test 图片,但是没找到,最后在 xhdpi 文件夹下找到,然后会自动根据 density 计算并缩放显示出 来,实际显示出来的大小是 120/2=60px, 所以整体的显示比例才会看起来比较正常

mdpi

xhdpi

但是如果你在 mdpi 文件夹里也放入了同样的图片,那么 mdpi 的设备会直接去 mdpi 文件夹里寻找到 test 图片,并直接显示,而这时候显示不会缩放,实际显示大小就是 120X120,在 mdpi 的屏幕上看起来就会比较大,如图:

通过上面整个过程,大家应该理解了 Android 加载资源的整个过程, wrap_content 同样可以用 dp 来代替,就拿上面这个例子,在 xhdpi 文件夹内放入了一张 120X120 像素的 test 图片,宽高直接除 density 就得出 dp 的数值,即这种情况下以下代码是等同的.

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/test" />
<ImageView
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:src="@drawable/test" />

总结

相信通过以上的讲解,对 Android UI 中的一些基本概念有个很好的理解,实际开发工作中也有一些高效的方法可以参考,应该可以应对大部分的屏幕适配工作。但是项目中仍然有一些比较特殊的适配需求满足不了,以后会针对一些特殊的需求进行示例讲解。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

哆啦不做梦

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

13886483628

文章 0 评论 0

流年已逝

文章 0 评论 0

℡寂寞咖啡

文章 0 评论 0

笑看君怀她人

文章 0 评论 0

wkeithbarry

文章 0 评论 0

素手挽清风

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文