`
亚当爱上java
  • 浏览: 703627 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

深入理解Android的密度独立性

 
阅读更多

前言

安卓是一个只对硬件设备限制有很少限制的移动操作系统。生产商们几乎可以创造任何形状的、尺寸的和密度的屏幕的设备。设备可以有物理键盘和按钮或者只有虚 拟键盘和按钮。由于它的设备客制化的自由性给软件开发者们制造了一些麻烦。首先,应用软件怎样在各种各样的设备上保证一致的用户体验呢?其次,应用软件怎 样利用一些拥有高端硬件或者独特特性的设备的优势呢?安卓在当初研发的时候就考虑了这些,给开发者提供了一些工具去支持各种配置的设备,优化了不同配置的 设备的用户体验,这些将在下面介绍。

为了应用程序的灵活性和兼容任何配置的设备,认真思考合适的跨配置的用户体验是必须的。创建一个Android应用程序时,设计者和开发者必须创建一个无 论是在小尺寸的手机上还是在大尺寸的平板上都能运行良好的UI界面。他们还要考虑图片资源对高密度和低密度的屏幕的优化。这篇BLOG的中心就是安卓怎样 支持不同密度的屏幕。

安卓的基本设计思想就是保证用户界面中的元素拥有相同的物理大小,而不论屏幕的密度。为什么呢?很简单,无论什么样的屏幕密度一个用户的手指的物理尺寸是 不变的。按键或者可以按的元素在任何设备上应该渲染成和手指物理大小一样尺寸(比手指印大一点)。文本和字母在不同的设备上也应该渲染成一样的字体大小 (可读的)。

 

屏幕密度不等于分辨率

屏幕像素密度是分辨率和显示尺寸的比值,可以用每英寸像素点或者dpi来度量。dpi越高,每个像素点越小也就越清晰。简单地说,dpi越高就意味着每英 寸显示的细节越多,而不是直接取决于高分辨。举个例子,Galaxy Nexus(对角线 4.65'')分辨率为:720x1280,Nexus 7(对角线 7'')分辨率为:800x1280.常见的错误观点是认为他们拥有相同的屏幕像素密度,因为它们的分辨率几乎一样。然而,Galaxy Nexus 的屏幕像素密度约为316dpi,Nexus 7的屏幕像素密度为216dpi,相差甚远。这是因为虽然它们拥有一样的分辨率,但是它们显示尺寸却不一样。再次说明,屏幕像素密度是分辨率和显示尺寸的 比值,两个因素一起决定屏幕像素密度。

 

密度级别

无数的Android设备的像数密度各不相同,分布为100dpi到480dpi以上。为那些不同密度的屏幕优化图片,就必须创建不同分辨率的图片。然 而,尝试为所有的像数密度优化所有的图片资源将会使是让人无法想象的无聊乏味,同时引起应用程序大小变的臃肿,简单的方法是不可行的。作为折衷方 案,Android用密度级别的概念把拥有确定密度范围的设备分类。这样应用程序只需要针对每个密度级别来优化图片,而不是针对所有可能的像素密度来优 化。这使得设计者和开发者的工作负担是合理的,时阻止了应用程序大小的膨胀。当然,代价就是:不同像素密度的设备上图片渲染后的物理尺寸是大小不一的,这 点将会在后面介绍。

 

因此,设计者和开发者如何根据密度块来优化图片资源?首先,要决定的是图片的呈现尺寸。例如,一个图标试图在屏幕中呈现  0.5x0.5的大小。下一步,创建一个图片支持的最大密度,或者是一个可伸缩的矢量图。最好的做法是支持最大的密度,当前是在xxhdpi 就在480dpi.在480dpi,一张0.5x0.5的图片转换为240x240px.一旦图形资源的最大密度版本被创建在240x240px.那么它 就可以在随后创建的密度块版本被适当的缩小比例,每个版本用相同的文件名。Google建议不要在213dpi创建tvdpi版本,因为它仅仅是被特定的 应用程序所需要,并且被一小撮设备而使用。一旦所有的版本被创建,它们可以被添加到drawable文件夹,并且用资源标识符告诉Android系统每一 种密度块所需要的大小。最后,参考一下在xml布局层的图形资源,然后通过编码它们的名称在R文件中生成,R文件是一个可以在程序中引用所有资源的文件。 Android系统会在运行时加载资源,并尽它最大的努力去匹配实际的设备配置与资源标识符应用。假如任何图片资源的密度版本没有被包括在 内,Android将用另外的密度版本并且将它缩小到所需要的合适的尺寸大小。当然,不推荐让Android系统来这样做。因为Andorid系统在操作 图片资源时并没有图片编辑软件操作的更加有 效和精确。

 

尺寸单位

在安卓中,用户界面可以在xml文件中创建或在在代码中实现。有几种单位可以用来表示一个表单的长宽。它们可以用在很多元素上来设定宽、高、外间距、内间距等等。

px——屏幕上真实的像素。这是一个与像素密度有关联的单位,一px单位的物理大小取决于屏幕的像素密度。

in——屏幕上的物理英寸。这是一个与像素密度无关联的单位,一in单位的物理大小在任何像素密度的屏幕上都是一样大的。一in单位转化为多少px单位取决于屏幕的像素密度。

mm——屏幕上的物理毫米。这是一个与像素密度无关联的单位,一mm单位的物理大小在任何像素密度的屏幕上都是一样大的。25.4mm等于一in。mm单位转化为多少px单位取决于屏幕的像素密度。

pt——点,屏幕上普通字体大小单位。这是一个与像素密度无关联的单位,一pt单位的物理大小在任何像素密度的屏幕上都是一样大的。72pt等于一in。一pt单位转化为多少px单位取决于屏幕的像素密度。

dp——像素密度无关联的像素单位。这是一个与像素密度无关联的单位。然而一dp单位的物理大小在不同的像素密度屏幕上只是近视的相等。大约160dp等于一in。在一dp转化为160dpi中的一个比例因子是与设备的密度级别相关联的。一dp等于多少像素取决于屏幕的像素密度和设备所属的密度级别。

sp——大小独立的像素单位,特地指定text的大小。这是一个与像素密度无关联的单位。然而一sp单位的物理大小在不同的像素密度屏幕上只是近视的相等。在一sp转化为160dpi中的一个比例因子是与设备的密度级别以及字体表现的大小相关联的。一sp等于多少像素取决于屏幕的像素密度和设备所属的密度级别。

 

http://static.oschina.net/uploads/img/201304/23112447_8Zj2.png
 

 

神奇的“dp”

如前面讨论的那样,"px"不是密度独立的,并且在不同的设备上拥有不同的大小,然而"in","mm"和"pt"是密度独立的,当然在不同的设备上拥有相同的大小。但是,"dp"和"sp"跟其余的有一些不同,虽然他们是密度独立的,但是他们在 不同的设备上拥有不同的大小。这是为什么呢?答案是"dp"和"sp"是如何被计算成像素的。Android使用mdpi(160dpi)作为其标准密 度,这里 1dp就是1px。本质上来讲,"dp"可以被认为是在160 dpi上的“px”。这就是为什么160 dp转换为大约1 in。因此根据设备密度等级与标准的密度(mdpi)之间的比率来转换"dp"到"px"。

"dp"趋向于不同的物理大小的原因是由于相同的缩放因子被应用到整个密度桶。该缩放因子是计算密度桶dpi,而不是设备真实的 dpi。当设备的dpi不完全地与它的密度桶dpi相同的时候,相同数目的"dp"转换为相同量的"px"。这就会导致相同数目的"px"被显示到不同密 度的屏幕上,以不同的大小呈现出来。


上面的表格显示了100 dp如何在不同密度的设备上转换为"px"。100 dp应该大致地转化为0.625 in,并且完美地转换为bucket sizes。但是,当设备的dpi少于密度桶的dpi的时候,它的像素在物理上会更大,并且相同数目的"dp"会渲染得更大,反之亦然。

因此这就引出一个问题,为什么"dp"允许这种物理尺寸的变化?从根本上来说,android在物理尺寸上会牺牲一些精确度,目的是为了保持性能和显示质 量。由于利用android的密度桶比率(0.75:1.0:1.5:2.0:3.0)让"dp"缩放到"px",这就允许有极小的"px"舍入和简单的 估计。同时,由于缩放因子与密度桶比率成比例,“dp”会按比例显示为各种密度提供的图片资源。最后,当缩放图行的时候,最好保持接近整数和简单的分数,因为复杂的分数会导致图片颜色过渡异常和走样

 

定义UI元素的界限

当定义用户界面元素的长宽时有几个特别的选项可供选择,就像尺寸单位一样。

wrap_content——这个选项将会扩展元素的边界到足够的大小以致可以容纳它包含的内容(图片,文本等等),本质上,这个选项把元素设置成它最大子元素的大小,不会去调整元素的大小。

match_parent(fill_parent 在API 8中已过时)——这个选项会使元素适应父元素的大小,使用父元素最大的空间,减少间距。本质上,这使子元素为父元素允许的最大尺寸的大小,并且必要的时候会调整元素的大小。

dimension unit——这个选项设置元素的边界为精确地单位大小,这些单位上文已经讨论过。本质上,它会设置元素的边界为确定的单位大小,必要的时候会调整元素的大小。

Demo

为了解释这一切是如何一起工作的,创建并测试一个示例应用程序是必要的。例如,采用一个在密度为xhdpi或320dpi,200X200 px的图片的设计。简单起见,将图片资源命名为“android_logo”。利用密度在320dpi,200X200 px图像分辨率作为所需的物理尺寸,可替换的图像尺寸可以被计算出来。

                                  

                       密度为xhdpi (320dpi),200x200px 的图片

                

在计算完所需特定密度的图像尺寸后,他们能够在最大密度版本被缩小到相应的尺寸,如前面所解释的那样。接下来,每一个密度版本的图片,能够被放入到用相应资源标识符标记的“drawable”文件夹下。Android系统会根据设备上的配置,在运行时选择最佳的资源。

                                             

                                               有标识符的资源目录

现在,为了呈现保持密度独立的可能方式,利用每一种密度独立的尺寸单位,将该图片设置成相同的物理尺寸。因为"px"不是密度独立的,而"sp"是为text设计的,因此忽略它们。

                 

 

 

设备例子:xhdpi Bucket

通过使用一个布局,里面包含相同的图片,这些图片是利用各种尺寸单位设置相同的物理大小,它可以比较每个尺寸单位是如何工作的。当运行在320 dpi的模拟器上,图片会以完全相同的大小显示,每一个尺寸单位都是这样。这是意料之中的,因为模拟器的dpi完全匹配xhdpi(320 dpi)密度等级。但是,当运行在同样xhdpi 密度等级的Galaxy Nexus上时,图片的大小尺寸会有一些变化。

 320dpi 模拟器截图

           Galaxy Nexus 截图

 

经过检查发现,很显然用"wrap_content"和"dp"设置的图片在大小上是匹配的,与此同时,用"in","mm"和"pt"也是匹配的。但 是,这两组没有彼此匹配。到底发生了什么事情呢?如之前讨论,"wrap_content"和"dp"利用密度桶比率去适当地转换它们的尺寸。因此,图片 大小被计算到200x200 px。但是,Galaxy Nexus的实际屏幕密度并不是320 dpi,它是 315.3 xdpi和 318.7 ydpi。 因为实际的密度低于320 dpi的xhdpi密度,因此在实际设备上的像素点会比想象的0.625 in的物理大小更大。

当分析用"in","mm"和"pt"设置图片大小的时候,注意到每一个图片被转换为 197.1x199.2 px。如之前讨论,"in","mm"和"pt"都是利用实际设备的密度去转换它们的尺寸到像素。因为Galaxy Nexus的实际密度低于320 dpi的xhdpi密度,更少的像素需要被转换为0.625x0.625 in,这样图片就被缩小了。

当对所显示的图片进行对比时,很明显,用"wrap_content"和"dp"设置的图片物理尺寸精确度较低,但是它们的图片质量比"in","mm"和"pt"更好。


没有缩放"wrap_content"和"dp"(左)。有缩放"in","mm"和"pt"(右

 

 

设备例子: hdpi Bucket

下一步,当运行在240dpi的模拟器上时,图片以完全相同的大小显示每一个尺寸单元。重复一下,之所以期望这样是由于模拟器的dpi在240dpi的条 件下恰好匹配hdpi密度的桶(bucket)。但像以前一样,当运行于hdpi设备时,出现一个不可思议的事情,图像的尺寸有一些变化。

 

 

240dpi模拟器屏幕截图

                            

 

 

 

HTC Droid Incredible截图

像往常一样,HTC Droid Incredible显示150x150 px的图片,该图片用"wrap_content" 和"dp"设置。因为Droid Incredible的实际屏幕密度为254x254dpi,大于240dpi的hdpi密度,这意味着在屏幕上的像素小于240 dpi密度对应像素的大小。这就会导致150x150 px的图片显示要小于0.625 in的基础大小。用"in","mm"和"pt"设置的图片显示为158.8x158.8px,因为需要更多的像素点转换为0.625x0.625 in,这样该图片就会被放大。

就像在Galaxy Nexus上,用"wrap_content"和"dp"设置的图片物理尺寸精确度较低,但是它们的图片质量比"in","mm"和"pt"更好。


没有缩放"wrap_content"和"dp"(左)。有缩放"in","mm"和"pt"(右

你能在GitHub找到该demo所有的源码,或从后面的附件中获得。

 

尺寸单位最佳实践

px- 没有保持密度独立。应该永远不需要。

in/mm/pt- 保持密度独立,但是计算到确切数额的像素,会降低体验,还会导致图片颜色过渡不自然和走样。如果需要尺寸大小的精确度,并且任何偏差都是不可接受的,那选择in/mm/pt就是必要的。需要确切距离的时候,设置元素间的距离,in/mm/pt也是很有用的。

dp- 保持密度独立并且保持最佳图片质量,但是要在物理大小上,以小的偏差作为代价。因为它利用密度桶比率来进行计算大小,它适当地提供准确的尺寸与图片资源。这是被推荐使用的尺寸单位,用来设置元素间的界限或者之间的距离。

sp- 保持密度独立和字体的质量,但是要在物理大小上,以小的偏差作为代价。这是被推荐使用的尺寸单位,仅仅用来设置字体大小,因为它需要考虑密度和用户的文本大小偏好。

 

 

总结

总的来说,保持密度独立性的要点:

  • 确定每一个图像资源确定呈现该资源所需的物理尺寸
  • 设计尺寸比最大密度桶更大的矢量图像资源或原始图像资源
  • 为每一个密度桶创建特定的density 版本,然后将他们放入用合适标识符标识的“drawable”资源目录下
  • 当设置图像边界的时候,用“wrap_content”来获得最佳显示效果,用“match_parent”来充满整个显示区域,或者用“dp”来设定一个固定的尺寸
  • 当在布局里面设定距离的时候,用“dp”获得最佳显示效果。如果需要使用精确的尺寸,仅用“in”,"mm"或"pt"。在这里永远别使用"px"

随着对Android如何处理在不同密度的屏幕上显示的理解,这将使得在任何密度的显示屏上设计和开发最佳的应用程序变得更加容易。

 

英文原文:Understanding Density Independence in Android  翻译:OSchina

 

 

 

分享到:
评论

相关推荐

    Android屏幕大小和精度

    Android系统采用密度独立像素(DIP或dp)作为单位,使得开发者可以编写不依赖具体像素密度的代码,确保UI元素在不同设备上保持相对一致的大小。 二、术语和概念 1. 屏幕尺寸:屏幕尺寸通常指对角线长度,用于区分...

    Basic4android 手机屏幕PPI计算器源码

    4. **DIP(设备独立像素)和DP(密度无关像素)**:DIP和DP是Android中的单位,它们与PPI有关,用于处理不同密度屏幕的适配问题。1DP在所有屏幕密度下都代表相同的物理大小,系统会根据屏幕的PPI自动调整DIP的数量。...

    AndroidScreen 源码 eclipse项目

    通过分析和学习该项目的源码,我们可以深入理解Android的布局管理器、像素密度以及资源维度(dp、sp)等概念。 首先,Android系统采用了一种灵活的布局机制,允许开发者创建可自适应不同屏幕尺寸的界面。在Android...

    android UI界面开发图片

    首先,理解Android中的图片格式至关重要。Android支持多种图像格式,包括JPEG、PNG(推荐使用无损的PNG-24或有损的PNG-8)、WEBP等。其中,PNG格式由于其透明度支持和无损压缩,常用于图标和图形元素;而JPEG适用于...

    在android中,同样一张图片在不同的分辨率中有不同的大小

    这涉及到Android的资源适配机制,包括密度独立像素(DP, Density Independent Pixel)的概念以及Android资源目录结构。 首先,Android设备有多种屏幕密度,如低密度(LDPI)、中密度(MDPI)、高密度(HDPI)、超...

    Android屏幕分辨率适配

    首先,我们需要理解Android的屏幕尺寸分类,它分为小(small)、正常(normal)、大(large)和超大(xlarge)四种。这些分类基于屏幕的对角线长度,适用于不同的手持设备。同时,分辨率分为低、中、高和超高,例如MDPI...

    Qt on Android可伸缩界面

    首先,理解Android的屏幕密度和尺寸至关重要。Android设备有多种屏幕密度,如低密度(ldpi)、中密度(mdpi)、高密度(hdpi)、超高密度(xhdpi)和超超高清(xxhdpi)等。每种密度都有对应的像素比例,以确保图标...

    AndroidAutoSize.rar

    在Android应用开发中,屏幕适配一直是一个棘手的问题,尤其是在面对...通过深入研究`AndroidAutoSize-master`中的源码和示例,开发者可以更好地理解并应用`AndroidAutoSize`,从而提高应用的屏幕适配质量和开发效率。

    android UI自适应验证

    - Android使用资源密度目录(如`res/layout`、`res/layout-mdpi`、`res/layout-xhdpi`等)来实现布局的密度独立性,确保不同密度的设备上UI元素大小相对一致。 - `layout-sw`尺寸限定符:用于定义最小可使用宽度,...

    android适配项目源码和文档教程

    "android适配项目源码和文档教程"提供了宝贵的资源,帮助开发者深入理解并实践Android设备的适配策略。 首先,让我们探讨Android适配的基本概念。Android系统支持多种屏幕尺寸,包括小屏、中屏、大屏和超大屏,以及...

    Android-Calces一个Android组件化自动构建脚本

    在本文中,我们将深入探讨Android-Calces的核心功能、工作原理以及如何在项目中使用它。 首先,让我们理解什么是组件化。在Android应用开发中,组件化是一种架构设计策略,它将大型项目分解为独立、可重用的模块或...

    【Android Studio代码】层布局

    2. **android:textSize**:此属性用来设定TextView中文字的大小,单位可以是sp(可缩放像素)或dp(密度独立像素)。使用sp作为单位时,字体大小会根据用户的字体缩放偏好进行调整,保证了可访问性。开发者通常会...

    解析android中的dip,dp,px,sp和屏幕密度

    本文将深入解析Android中的dip, dp, px, sp这四个关键概念,以及它们与屏幕密度的关系。 1. dip(设备独立像素) dip,全称device independent pixels,是Android中用来实现跨设备一致性显示的单位。它不受物理像素...

    直接输入px自动适配所有android机型

    实现这一功能的关键在于理解Android的密度独立像素(dp)系统和屏幕密度转换。dp是一种虚拟像素单位,它与物理像素的关系是动态的,会根据设备的屏幕密度进行调整。1dp在不同密度的屏幕上对应的实际像素数量不同,...

    Android实现两块屏幕分屏显示

    首先,理解Android的分屏模式。自Android 7.0(Nougat)开始,系统原生支持了多窗口模式,允许用户同时打开两个应用并占据屏幕的一部分,从而实现分屏显示。但在工控机环境下,可能需要更高级的定制化方案,例如针对...

    android小项目城市天气插件

    这个项目对于初学者来说是一个很好的学习平台,可以深入理解Android Widget的开发流程和注意事项。在这个项目中,我们将探讨以下几个关键知识点: 1. **Android Widget**: Android Widget是Android系统提供的一种轻...

    Android之仿“知天气”动态折线图和outlook抽屉效果

    总结来说,这个项目涉及到了Android中的自定义视图、动画效果、手势识别和用户界面设计等核心知识点,对于想要深入理解Android开发的程序员来说,是一个非常有价值的实践案例。通过学习和研究这个项目,不仅可以掌握...

    Android UI界面源码.rar

    Android提供了多种密度独立像素(dp/dip)和比例缩放因子,确保应用在各种设备上都能正常显示。源码可能展示了如何利用dimens.xml文件进行尺寸定义,以及如何使用swXXdp资源目录来实现屏幕尺寸依赖的布局。 通过...

    android屏幕适配

    DP,密度独立像素,是一种抽象单位,用于表示像素密度无关的尺寸。它考虑了不同设备的像素密度,使得在不同屏幕上的视觉效果保持一致。而PX是物理像素,每个设备的像素密度可能不同,直接使用PX可能导致在高密度屏幕...

    dpiTest android 检测手机分辨率

    dp是Android开发中的一个虚拟单位,它是独立于设备像素密度的,旨在提供一种跨设备尺寸和密度的统一测量方式。1dp在160dpi的设备(即mdpi设备)上等于1px。而px则是实际屏幕上的像素点,它是硬件级别的,会受到设备...

Global site tag (gtag.js) - Google Analytics