Android 关于dp dip sp px dpi density解析

2024-02-25 22:58
文章标签 android dp 解析 sp density dip px dpi

本文主要是介绍Android 关于dp dip sp px dpi density解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.px

px即像素 (Pixel),1px代表了手机屏幕上一个物理的像素点。由于以px为单位的控件在不同手机上显示大小不一定相同,故Android不推荐使用px来设置控件大小:
px例子

2.分辨率

分辨率通常表示为横轴像素长度和纵轴像素长度的乘积,如320*480等。

3.dpi

dpi的全称是Dots Per Inch,即点每英寸,一般被称为像素密度,它代表了一英寸里面有多少个像素点。计算方法为屏幕总像素点(即分辨率的乘积除以屏幕大小),常见的取值有120,160,240。

举例:


比如说这里有一款1920*1200分辨率的7寸平板,根据勾股定理,我们可以算到对角线的像素点约为2264,则其像素密度(dpi)为2264 / 7 = 323

4.density

density直译为密度,它的计算公式为屏幕dpi除以160点每英寸,由于单位除掉了,故density只是一个比值,常见取值为1.0,1.5等。
在Android中我们可以通过下面代码获取当前屏幕的density:
getResources().getDisplayMetrics().density;

5.dp(dip)

dp,也叫做dip,全称为Density independent pixels,叫做设备独立像素。他是Android为了解决众多手机dpi不同所定义的单位,谷歌官方的解释如下:
Density-independent pixel (dp) 
  A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way. 
The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a "medium" density screen. At runtime, the system transparently handles any scaling of the dp units, as necessary, based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels. You should always use dp units when defining your application's UI, to ensure proper display of your UI on screens with different densities.
从上文我们可以看出,dp是一种虚拟抽象的像素单位,他的计算公式为:px = dp * (dpi / 160) = dp * density。因此在dpi大小为160的手机上,1dp = 1px,而在dpi大小为320的手机上,1dp = 2px,即在屏幕越大的手机上,1dp代表的像素也越大。因此我们定义控件大小的时候应该使用dp代替使用px。

6.sp

sp是Android中定义字体大小的一种单位,全称为Scaled Pixels,叫做放大像素。sp会根据用户手机上设定的字体大小而改变,在用户手机字体大小设置为正常的情况下,1sp = 1dp。
sp与px之间的密度比例可以通过如下代码获取:
getResources().getDisplayMetrics().scaledDensity; 

7.资源文件分辨率

一般而言,我们存放资源文件的目录(res)会有多个子目录,这些子目录代表了不同系统屏幕分辨率:
密度ldpimdpihdpixhdpixxhdpixxxhdpi
中文低分辨率中分辨率高分辨率超高分辨率超超高分辨率超超超高分辨率
dpi120以下120~160160~240240~320320~480480~640
分辨率240*320320*480480*800720*12801080*19203840*2160
比例34681216

当我们在手机上加载资源时,系统首先会从手机对应分辨率等级的子目录下找资源文件,如果找不到的情况下,会使用别的分辨率的文件进行缩放处理。

8.找不到对应分辨率资源文件情况

对于drawable资源,当应用在设备对应dpi目录下没有找到某个资源时,遵循“先高再低”原则,会从附近的分辨率获取图片,然后按比例进行缩放:

比如,当前为xhdpi设备,并且只有以下几个目录,则drawable的寻找顺序为: 
xhdpi->xxhdpi->xxxhdpi(如果没有更高的了)->nodpi(如果有的话)->hdpi->mdpi,如果在xxhdpi中找到目标图片,则压缩2/3来使用,如果在mdpi中找到图片,则放大2倍来使用。

因此,以现在主流设备来说一般可能在drawable-xxhdpi放置一份即可,这样可以尽量避免Android为我们放大图片所导致的OOM

对于values资源,当应用设备在当前dpi对应目录的demins.xml中没有找到目标条目时,采用“就近匹配”原则:

比如,当前为hdpi设备,并且只有以下几个目录,则values的寻找顺序为: 
hdpi->xhdpi->mdpi->values,即先向上级dpi目录查找,再向下级dpi目录查找,最后一路向下查找到values目录,如果values下都找不到,就只有找values-ldpi,当然,现在有这个目录的应用不多了。

附:dp与px,sp与px转换的代码

public class DisplayUtil { /*** 将px值转换为dip或dp值,保证尺寸大小不变* */ public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } /*** 将dip或dp值转换为px值,保证尺寸大小不变* */ public static int dip2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); } /*** 将px值转换为sp值,保证文字大小不变* */ public static int px2sp(Context context, float pxValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (pxValue / fontScale + 0.5f); } /*** 将sp值转换为px值,保证文字大小不变* */ public static int sp2px(Context context, float spValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } }


这篇关于Android 关于dp dip sp px dpi density解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/746963

相关文章

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Java MCP 的鉴权深度解析

《JavaMCP的鉴权深度解析》文章介绍JavaMCP鉴权的实现方式,指出客户端可通过queryString、header或env传递鉴权信息,服务器端支持工具单独鉴权、过滤器集中鉴权及启动时鉴权... 目录一、MCP Client 侧(负责传递,比较简单)(1)常见的 mcpServers json 配置

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Java Scanner类解析与实战教程

《JavaScanner类解析与实战教程》JavaScanner类(java.util包)是文本输入解析工具,支持基本类型和字符串读取,基于Readable接口与正则分隔符实现,适用于控制台、文件输... 目录一、核心设计与工作原理1.底层依赖2.解析机制A.核心逻辑基于分隔符(delimiter)和模式匹

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装