Android开发-之屏幕适配

Android开发-之屏幕适配

前言

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

屏幕像素点的计算公式如下:
在这里插入图片描述
即,先用勾股定理计算出对角上的像素点数量,再用该数量除以屏幕尺寸。

例如:4.7 英寸,1080 * 1920 分辨率的手机,它的像素密度为:
在这里插入图片描述
对于 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,他们之间的转换关系如下所示:
在这里插入图片描述
在这里插入图片描述
由此可见,在设备屏幕密度为 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 限定符适配方案 显然更加合适。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/460806.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Chrome插件的Chatgpt对话无损导出markdown格式(Typora完美显示)

刚刚提交插件到Chrome插件商店正在审核,想尝试的可以先使用: https://github.com/thisisbaiy/ChatGPT-To-Markdown-google-plugin/tree/main 我将源代码上传至了GitHub,欢迎star, IssueGoogle插件名称为:ChatGPT to MarkDown plus…

STM32输出PWM波控制180°舵机

时间记录:2024/2/8 一、PWM介绍 (1)脉冲宽度调制 (2)占空比:高电平时间占整个周期时间的比例 (3)STM32通过定时器实现PWM时具有两种模式 PWM1模式:向上计数模式下&…

Guava RateLimiter单机实战指南

欢迎来到我的博客,代码的世界里,每一行都是一个故事 Guava RateLimiter单机实战指南 前言maven坐标引入业务实现重要参数和方法关于warmupPeriod实战 前言 想象一下你是一位大厨,正在烹饪美味佳肴。突然之间,前来就餐的人潮如潮水…

如何判断线程池已经执行完所有任务了?

目录 不判断的问题 方法1:isTerminated 缺点分析 扩展:线程池的所有状态 方法2:getCompletedTaskCount 方法说明 优缺点分析 方法3:CountDownLatch(推荐) 优缺点分析 方法4:CyclicBar…

第五篇【传奇开心果系列】vant开发移动应用示例:深度解读高度可定制

传奇开心果博文系列 系列博文目录Vant 开发移动应用示例系列 博文目录前言一、Vant高度可定制的重要作用二、样式定制介绍和示例代码三、组件定制介绍和示例代码四、组件库定制介绍和示例代码五、主题定制介绍和示例代码六、语言环境定制介绍和示例代码七、资源加载定制介绍和示…

电视盒子哪个牌子好?经销商整理线下热销电视盒子排名

买电视盒子的时候不懂电视盒子哪个牌子好的朋友超级多,近来我看到很多网友在讨论电视盒子,我按照店内的销量情况整理了热销电视盒子排名,跟着我一起看看目前实体店最受欢迎的电视盒子都有哪些吧。 NO.1 泰捷WEBOX WE40S电视盒子 推荐理由&am…

创新指南|生成式AI实验 - 企业快速渐进采用人工智能的科学新方法

生成式人工智能(Gen AI)正迅速成为各行各业的企业创新焦点。 生成式AI实验对于企业创新而言至关重要,不仅可以帮助企业识别最适合和最有影响的应用场景,还能促进组织沿着生成式 AI 学习曲线前进,建立早期的创新领导者和…

zer0pts-2020-memo:由文件偏移处理不正确--引发的堆溢出

启动脚本 #!/bin/sh qemu-system-x86_64 \-m 256M \-kernel ./bzImage \-initrd ./rootfs.cpio \-append "root/dev/ram rw consolettyS0 oopspanic panic1 kaslr quiet" \-cpu kvm64,smep,smap \-monitor /dev/null \-nographic -enable-kvm/ # dmesg | grep page …

OpenAI推出ChatGPT已经过去一年多了,AI 取代了内容创作者吗

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

Docker容器监控-CIG

目录 一、CIG说明 1. CAdvisor 2. InfluxDB 3. Grafana 二、环境搭建 1. 创建目录 2. 编写 docker-compose.yml 3. 检查并运行容器 三、进行测试 1. 查看 influxdb 存储服务 是否能正常访问 2. 查看 cAdvisor 收集服务能否正常访问 3. 查看 grafana 展现服务&#…

蓝桥杯备赛Day9——链表进阶

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5]示例 2: 输入:head = [1], n = 1 输出:[]示例 3: 输入:head = [1,2], n = 1 输出:[1]提示: 链表中结点的数目为 sz1 <= sz <= 300 &l…

【软件激活_01】2024年Pycharm激活码

Pycharm激活码 关注公众号世说CV回复pycharm获得最新激活码。 效果 公众号图片