20130526早读课:理解 Android 的密度独立
推荐理由:对于很多安卓平台设计的初学者来说,很容易搞混px、dp、pt、sp等单位在安卓上的意义。而原文作者用通俗的语言对比了它们之间的差距,一起来看看吧。
前言
安卓是一个只对硬件设备限制有很少限制的移动操作系统。生产商们几乎可以创造任何形状的、尺寸的和密度的屏幕的设备。设备可以有物理键盘和按钮或者只有虚拟键盘和按钮。由于它的设备客制化的自由性给软件开发者们制造了一些麻烦。首先,应用软件怎样在各种各样的设备上保证一致的用户体验呢?其次,应用软件怎样利用一些拥有高端硬件或者独特特性的设备的优势呢?安卓在当初研发的时候就考虑了这些,给开发者提供了一些工具去支持各种配置的设备,优化了不同配置的设备的用户体验,这些将在下面介绍。
为了应用程序的灵活性和兼容任何配置的设备,认真思考合适的跨配置的用户体验是必须的。创建一个Android应用程序时,设计者和开发者必须创建一个无论是在小尺寸的手机上还是在大尺寸的平板上都能运行良好的UI界面。他们还要考虑图片资源对高密度和低密度的屏幕的优化。这篇BLOG的中心就是安卓怎样支持不同密度的屏幕。
安卓的基本设计思想就是保证用户界面中的元素拥有相同的物理大小,而不论屏幕的密度。为什么呢?很简单,无论什么样的屏幕密度一个用户的手指的物理尺寸是不变的。按键或者可以按的元素在任何设备上应该渲染成和手指物理大小一样尺寸(比手指印大一点)。文本和字母在不同的设备上也应该渲染成一样的字体大小(可读的)。
屏幕密度不等于分辨率
屏幕像素密度是分辨率和显示尺寸的比值,可以用每英寸像素点或者dpi来度量。dpi越高,每个像素点越小也就越清晰。简单地说,dpi越高就意味着每英寸显示的细节越多,而不是直接取决于高分辨。举个例子,Galaxy Nexus(对角线 4.65”)分辨率为:720×1280,Nexus 7(对角线 7”)分辨率为:800×1280.常见的错误观点是认为他们拥有相同的屏幕像素密度,因为它们的分辨率几乎一样。然而,Galaxy Nexus 的屏幕像素密度约为316dpi,Nexus 7的屏幕像素密度为216dpi,相差甚远。这是因为虽然它们拥有一样的分辨率,但是它们显示尺寸却不一样。再次说明,屏幕像素密度是分辨率和显示尺寸的比值,两个因素一起决定屏幕像素密度。
密度级别
无数的Android设备的像数密度各不相同,分布为100dpi到480dpi以上。为那些不同密度的屏幕优化图片,就必须创建不同分辨率的图片。然而,尝试为所有的像数密度优化所有的图片资源将会使是让人无法想象的无聊乏味,同时引起应用程序大小变的臃肿,简单的方法是不可行的。作为折衷方案,Android用密度级别的概念把拥有确定密度范围的设备分类。这样应用程序只需要针对每个密度级别来优化图片,而不是针对所有可能的像素密度来优化。这使得设计者和开发者的工作负担是合理的,时阻止了应用程序大小的膨胀。当然,代价就是:不同像素密度的设备上图片渲染后的物理尺寸是大小不一的,这点将会在后面介绍。
因此,设计者和开发者如何根据密度块来优化图片资源?首先,要决定的是图片的呈现尺寸。例如,一个图标试图在屏幕中呈现 0.5×0.5的大小。下一步,创建一个图片支持的最大密度,或者是一个可伸缩的矢量图。最好的做法是支持最大的密度,当前是在xxhdpi 就在480dpi.在480dpi,一张0.5×0.5的图片转换为240x240px.一旦图形资源的最大密度版本被创建在240x240px.那么它就可以在随后创建的密度块版本被适当的缩小比例,每个版本用相同的文件名。Google建议不要在213dpi创建tvdpi版本,因为它仅仅是被特定的应用程序所需要,并且被一小撮设备而使用。一旦所有的版本被创建,它们可以被添加到drawable文件夹,并且用资源标识符告诉Android系统每一种密度块所需要的大小。最后,参考一下在xml布局层的图形资源,然后通过编码它们的名称在R文件中生成,R文件是一个可以在程序中引用所有资源的文件。Android系统会在运行时加载资源,并尽它最大的努力去匹配实际的设备配置与资源标识符应用。假如任何图片资源的密度版本没有被包括在内,Android将用另外的密度版本并且将它缩小到所需要的合适的尺寸大小。当然,不推荐让Android系统来这样做。因为Andorid系统在操作图片资源时并没有图片编辑软件操作的更加有 效和精确。
尺寸单位
在安卓中,用户界面可以在xml文件中创建或在在代码中实现。有几种单位可以用来表示一个表单的长宽。它们可以用在很多元素上来设定宽、高、外间距、内间距等等。
px——屏幕上真实的像素。这是一个与像素密度有关联的单位,一 px单位的物理大小取决于屏幕的像素密度。
i n——屏幕上的物理英寸。这是一个与像素密度无关联的单位,一 in单位的物理大小在任何像素密度的屏幕上都是一样大的。一 in单位转化为多少 px单位取决于屏幕的像素密度。
mm——屏幕上的物理毫米。这是一个与像素密度无关联的单位,一 mm单位的物理大小在任何像素密度的屏幕上都是一样大的。25.4 mm等于一 in。一 mm单 位转化为多少 px单位取决于屏幕的像素密度。
pt——点,屏幕上普通字体大小单位。这是一个与像素密度无关联的单位,一 pt单位的物理大小在任何像素密度的屏幕上都是一样大的。72 pt等于一 in。 一 pt单 位转化为多少 px单位取决于屏幕的像素密度。
dp——像素密度无关联的像素单位。这是一个与像素密度无关联的单位。然而一 dp单位的物理大小在不同的像素密度屏幕上只是近视的相等。大约160 dp等于一 in。在一 d p转化为160 dp i中的一个比例因子是与设备的密度级别相关联的。一 dp等于多少像素取决于屏幕的像素密度和设备所属的密度级别。
s p——大小独立的像素单位,特地指定text的大小。这是一个与像素密度无关联的单位。然而一 sp单位的物理大小在不同的像素密度屏幕上只是近视的相等。在一 sp转化为160 dpi中的一个比例因子是与设备的密度级别以及字体表现的大小相关联的。一 sp等于多少像素取决于屏幕的像素密度和设备所属的密度级别。
神奇的“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设计的,因此忽略它们。
尺寸单位最佳实践
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
如果看到这段文字,证明您已经看完这篇文章了,有什么收获有什么感想有什么不赞同,我们期待您的留言评论,并诚挚邀请您加入“互联网er早读课”QQ群,一同交流每天文章的心得并结识同行。官方3群:42447965,加群密码“职业信息+城市+姓名”,否则不予通过,入群后请修改群名片。注:官方QQ群非水群,喜欢闲聊的童鞋请勿加入。再次感谢您对早读课网站的支持。
我们猜您可能也喜欢: | ||||
20130524早读课:为日渐成熟的Android设计 |
20121227早读课:Android与iOS在交互细节上的差异 |
20130415早读课:重视Android Design,别再照搬iOS UI |
20121019早读课:创业不挡巨人路,产品核心在后端 |
20121128早读课:通过手绘元素提升产品的个性与亲和力 |
无觅 |