Android图片资源
title: 2016-5-5未命名文件
tags: UI适配,图片资源
grammar_cjkRuby: true
概述:
本文整理了Android开发中,图片资源的提供方式和使用方式。包括图片文件的文件组织,nine-path图片,系统选择不同设备针对的图片时的规则等。可以在Android开发文档中,Develop > API Guide > App Resources 目录找到有关应用资源的更全面的介绍。
Note: 在Android 3.2之后的版本,有新的资源组织方式,本文只侧重关于早先的资源的组织方式的整理。
1.为什么提供不同设备配置的资源文件
除代码外,资源文件也是安卓程序中必不可少的部分,如图片、布局文件,甚至是音频、视频等原始多媒体文件。不同于代码文件的是,UI资源文件是和设备的显示器密切相关的。目前,Android设备的配置种类繁多——不同的屏幕尺寸,分辨率,以及用户使用时的不同的屏幕方向等。为了让自己的程序运行在多种不同的尺寸上都表现良好,Android系统提供了很多有用的方式。例如,为不同的尺寸和分辨率的屏幕提供不同的图片资源,这样可以让你的应用在不同的设备上显示最适合此设备分辨率/尺寸的不同大小的图片。
总之,在UI表现上,考虑为不同设备提供不同的资源是必不可少的做法。
2.Android屏幕配置相关概念
2.1 像素pixel/px
像素就是显示器上显示的一个最小的点,整个显示屏就是一个由像素点组成的矩形。例如720*1280的像素就是说屏幕在横竖分别有720和1280个可显示的点。目前来讲像素点都是一个正方形的“点”,它是最小的显示单位。
2.2 PPI
Pixels Per Inch:每英寸的像素数,表示每英寸所拥有的像素数量。因此PPI数值越高,即代表显示屏能够以越高的密度显示图像。
2.3 DPI
Dot Per Inch:每英寸的点数。这里的“点”是一个抽象概念,例如打印机中,点就是。。。在电子显示器中,DPI和PPI通常是混用的。
DPI和PPI都是描述设备的显示密度的,它们本身不是长度单位,而是一个密度系数。
2.4 像素密度
Android中对图片的分类是通过Screen pixel density (像素密度:以dpi为数值单位)进行的,包括ldpi、mdpi、hdpi、xhdpi这四个主要的级别。
ldpi: Low-density screens; approximately 120dpi.
mdpi: Medium-density (on traditional HVGA) screens; approximately 160dpi.
hdpi: High-density screens; approximately 240dpi.
xhdpi: Extra high-density screens; approximately 320dpi。
xhdpi:480dpi。
这四种屏幕密度之间存是3:4:6:8的缩放比例,所以,一个ldpi下的9x9像素的bitmap(位图)在mddpi下就是12x12,在hdpi下是18x18,在xhdpi下是24x24。
2.5 Android对屏幕的分类
Android用两个属性size和density
来对屏幕分类:
屏幕尺寸:small, normal, large, xlarge,xxlarge。
- xlarge :screens are at least 960dp x 720dp
- large screens are at least 640dp x 480dp
- normal :screens are at least 470dp x 320dp
- small :screens are at least 426dp x 320dp
像素密度:low (ldpi), medium (mdpi), high (hdpi), extra high (xhdpi), extra extra high (xhdpi)。
屏幕尺寸和像素密度都有各自的分级,它们是相互独立的。大屏幕可以是小的分辨率,而小屏幕可以是大分辨率。
2.6 DP的使用
对于Android开发,布局文件中可以使用px(pixel像素)这样的绝对单位,而更多情况下,根据Android开发的适配方式,应使用的UI元素的大小单位是“dp”即“dip”,device independent pixels(设备独立像素)。
它是一个虚拟的像素单位,以像素无关的方式来表示UI元素的尺寸和位置。
设备最终显示时,UI上的任何元素都是需要一个具体的像素值的,那么dp是如何转换为最终的像素值的?
正如DIP它的名字,它表示一种逻辑单位,和实际pxiel之间存在着转换关系,系统会自动在不同设备像素密度时把以dp为单位的大小缩放为合适的具体像素值。
具体做法是:
像素密度分级mdpi为基准,它的dpi值为160,此时1dp = 1px。对于运行程序的设备,Android系统会根据其尺寸和屏幕像素来计算出它的像素密度分级。不同像素密度下dp和px的转换不同,公式是: px = dp * (dpi / 160),根据公式可以知道,不同像素密度下的dp转换为px时对应的缩放比例和它们之间的dpi值是成正比的。那么在xhdpi下,其dpi为320,则1dp为2px,正好是mdpi的2倍。
下面是bitmap的例子:
在为应用提供bitmap资源时,应该保证图片可以正确被缩放到不同的像素密度级别。
对于一个图片,它在不同像素密度级别下的缩放系数如下:
- xhdpi: 2.0
- hdpi: 1.5
- mdpi: 1.0 (参考标准)
- ldpi: 0.75
如果在xhdpi的设备下使用的合适的图片尺寸是200x200,那么在hdpi下图片应该是150x150,在mdpi下是100x100,在ldpi下是75x75.
目前手机的像素密度至少都在mdpi及以上,所有通常只提供xhdpi和xxhdpi下的图片即可,像素密度小的设备,Android系统会将位图进行合适的缩放。
以dp为尺寸和位置,使得UI元素在不同屏幕上拥有一致的表现。原理就是“等比缩放”,方式就是dp,dp的概念和对应px的计算方式如上面所记。即便使用dp来在不同的dpi下进行缩放转换,如果屏幕的大小(例如同样的dpi但是一个是5寸、一个是8寸平板)、宽高比例(4:3、16:9、16:10等)是不一样的,还是会出现个别的UI显示问题。这就需要借助良好的UI布局设计来避免内容显示不全、错位...等问题。对于形形色色的屏幕,没有一种方案是万能的。
优缺点:
等比缩放:位图失真,没有充分利用大屏幕显示更多的内容。
不等比缩放:满足宽高都显示完整,其余的和等比缩放一样。
灵活的布局排版:设计上去避免不同尺寸的屏幕显示问题最好。
2.7 size和density资源组织的不同
The types of alternative resources you should create depends on your application's needs. Usually, you should use the size and orientation qualifiers to provide alternative layout resources and use the density qualifiers to provide alternative bitmap drawable resources.
为不同尺寸的屏幕提供不同特定的layout文件,对不同的像素米的屏幕提供不同的drawable资源。
3.多个备选图片资源的组织
以dp指定的宽高和位置数值,系统会自动缩放到合适的像素数值。对于drawable 资源(bitmap: .png, .jpg, and .gif 、Nine-Patch: .9.png),系统也会根据当前的设备像素密度来对它进行缩放——当为ImageView这样的控件指定以dp为单位的大小,或者为wrap_content时,在不同的像素密度的屏幕上其显示的像素大小是不一样的。若只提供单一的图片资源,在缩放后图片往往会变得模糊与期望不一样,所以图片,尤其是位图,需要针对不同的像素密度来提供不同的合适的像素尺寸的图片。
所以,需考虑对不同的像素密度的屏幕提供不同的图片资源。在Android项目中,图片资源的组织,正是按照pixel density来进行不同屏幕的分组。
drawable 资源放在res目录下不同的子目录中——使用不同的像素密度修饰符对应不同的像素密度:
- drawable-ldpi/ :对应ldpi
- drawable-mdpi/ :对应mdpi
- drawable-hdpi/ :对应hdpi
- drawable-xhdpi/ :对应xhdpi
- drawable-xxhdpi/ :对应xxhdpi
根据应用需要适配的屏幕范围,提供对应的图片资源到drawable-(density qualifiers)目录下。
Note: You only need to provide density-specific drawables for bitmap files (.png, .jpg, or .gif) and Nine-Path files (.9.png). If you use XML files to define shapes, colors, or other drawable resources, you should put one copy in the default drawable directory (drawable/).
4.系统对图片资源的选择规则和使用方式
对应一个代码中用到的图片资源,Android系统会使用以下步骤来选择出最适合当前运行设备的图片资源文件进行显示:
- 系统寻找匹配当前屏幕像素密度的可用图片文件。
例如当前设备屏幕像素密度分级为xhdpi则使用drawable-xhdpi目录下的文件。 - 如果没有找到匹配的文件,系统使用默认的图片资源,并对它进行缩放。
系统会使用合适的图片,进行缩放。例如,设备像素密度为ldpi,应用提供了hdpi的图片,那么系统会选择对hdpi的图片缩放0.5。最后的情况是,如果没有任何与当前像素密度合适的图片,系统选则默认的default resources(目录不包含配置修饰符,即drawable目录)——对应mdpi的像素密度。
为不同的密度的屏幕提供图片时,确保在统一的几个密度分级之间按照3:4:6:8的比例。
例如,假设在mdpi下提供的launcher icon为48x48像素,那么在其它密度下的尺寸分别为:
- 36x36 for low-density
- 48x48 for medium-density
- 72x72 for high-density
- 96x96 for extra high-density
5.UI适配的技巧
5.1 指导
- Use wrap_content, fill_parent, or dp units when specifying dimensions in an XML layout file ,Similarly, you should prefer the sp (scale-independent pixel) to define text sizes. The sp scale factor depends on a user setting and the system scales the size the same as it does for dp.
- Do not use hard coded pixel values in your application code
- Do not use AbsoluteLayout (it's deprecated)
- Use size and density-specific resources,Supply alternative bitmap drawables for different screen densities.
5.2 代码中dp和px的转换
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
6.Nine-Patch图片的使用
Android中提供两种方式在屏幕上绘制图像:Canvas、和Drawable。
Canvas: 代码中继承自View后重写onDraw等方法。
Drawable:resource images、resource XML、ShapeDrawable和Nine-patch。
静态图片资源(可以是多种备选)中.9.png是特殊的一种,在UI适配时很常用。
如果UI中使用到的位图需要在系统拉伸某个View之后依然填充此View(例如按钮的背景图片),那么就应该使用NinePatch图片,它的指定的部分可以被任意拉伸。所以,使用一个NinePatch就可以适配所有尺寸的屏幕。不过,对不同的密度的屏幕,依然需要提供不同的NinePatch。
九宫格图片是一种可拉伸的位图,在作为其它View的背景显示时,Android系统会自动将它改变到一个合适的大小。例如一个Button的长度随其显示的文本变化时,作为Button的背景的NinePatch图片也会自动被拉伸。
九宫格图片是一个标准的png文件,它包含一个额外的“1-像素-宽度”的边界。九宫格图片的名称必须以 .9.png作为后缀。针对不同像素密度的NinePatch图片放在不同的drawable-xxx里面。
NinePatch的边界用来定义它的可拉伸区域和静态区域(内容填充区域),通过在左、上边界上指定一个或多个1-pixel-wide黑色的线段——线段上的像素点就是可以在拉伸时被重复的点。这些线段在拉伸时保持相对的大小。
右、下边界可以分别指定1个线段(不能是多个)来确定背景的内容填充区——也就是View的内容可以填充的区域,类似padding地作用。如果不指定,那么系统以边长除去两边一像素的线段作为填充区域的线段。
由于Nine-patch图片的特殊使用方式,应该注意它的最小尺寸,保证有一个点的可拉伸区域。例如一个10像素半径的圆角矩形,边长至少为21,其中一个点是拉伸区域。
参考资料
在Android开发文档 4.4 中:
API Guide > Animation and Graphics > Canvas and Drawables
./sdk/docs/guide/topics/graphics/2d-graphics.htmlAPI Guide > App Resources > Providing Resources
./sdk/docs/guide/topics/resources/providing-resources.htmlAPI Guide > Best Practices > Supporting Multiple Screens
./sdk/docs/guide/practices/screens_support.htmlTraining > Getting Started > Supporting Different Devices
./sdk/docs/training/basics/supporting-devices/screens.htmlDesign > Style > Iconography
./sdk/docs/design/style/iconography.htmlTraining > Best Practices for User Interface > Designing for Multiple Screens
./sdk/docs/training/multiscreen/index.html
Android图片资源的更多相关文章
- 关于Android图片资源瘦身的奇思妙想
版权声明:本文由况鹰原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/77 来源:腾云阁 https://www.qcloud ...
- Hierarchyviewer定位Android图片资源的研究
之前就在研究能否通过Hierarchyviewer找到所有所见的资源 在导入Hierarchyviewer之后才发现绑定在View上的drawable与实际的图片资源之间并没有维系着一个固定的对应关系 ...
- android图片资源的适配问题
原文: http://hi.baidu.com/weiyousheng/blog/item/c622d701b9dec6c2277fb5cc.html 在之前的版本中,只有一个drawable,而2. ...
- 【转】Google推荐的命名规则——Android图片资源
http://blog.csdn.net/yy1300326388/article/details/45443477 1.译 资产类型 前缀 例子 图标 ic_ ic_star.png 启动图标 ic ...
- 读懂Android项目结构目录
我们看到下图:当我们创建了第一Android项目的时候有没有被吓到.怎么这么多目录,好头晕啊!没事, 那我们今天就了解一下这些目录是做什么的: src: src 目录是放置我们所有 Java 代码的地 ...
- 安卓Android基础—第一天
1.1G-4G的介绍 1G 大哥大 2G 小灵通 采用gsm标准(美国军方标准民用化) 发短信 3G 沃 72M/s 4G lte 100M/s 5G 华为 10G/s 小公司卖茶品大公司卖版权(标准 ...
- 跨平台移动框架iMAG开发入门
iMAG是一个非常简洁高效的移动跨平台开发框架,开发一次能够同一时候兼容Android和iOS平台,有点儿Web开发基础就能非常快上手.当前移动端跨平台开发的框架有非常多,但用iMAG另一个优点,就是 ...
- 谷歌开源图片压缩算法Guetzli实测体验报告
谷歌大神又出开源新技术啦,这次是对JPEG格式的图片采用全新算法重新编码,输出的图片还是JPEG但是图片大小明显缩小,而质量不但没有损失,甚至还更加优化,速速来体验一把. 一.环境安装 下载谷歌开源软 ...
- 腾讯QQ会员技术团队:以手机QQ会员H5加速为例,为你揭开sonic技术内幕
目前移动端越多越多的网页开始H5化,一方面可以减少安装包体积,另一方面也方便运营.但是相对于原生界面而言,H5的慢速问题一定被大家所诟病,针对这个问题,目前手Q存在几种方案,最常见的便是离线包方案,但 ...
随机推荐
- Lintcode 102.带环链表
------------------------ 只要设置两个指针,称为快慢指针,当链表没有环的时候快指针会走到null,当链表有环的时候快指针早晚会追上慢指针的. AC代码: /** * Defin ...
- CozyRSS开发记录17-Html2Xaml
CozyRSS开发记录17-Html2Xaml 1.RssContentView还需要优化 上回做了RssContentView的显示,但是对于rss返回的描述(摘要),连换行的没有,更别说里面还有h ...
- abstract与interface的区别
abstract的用法: //通过abstract 关键字修饰的类叫抽象类. abstract class Animal { String name; String color; abstract p ...
- Mysql调整字段顺序
1.增加(add/modify/change)一个字段使之位于第1列 alter table table_name add `id` int first; 2.增加一个字段使之位于某列后 alter ...
- jq size()与length的区别
size()跟length同样的功能,都是取元素的个数,那么他们的区别是什么呢,一个是方法一个是属性? 从图中可以看到size()方法比length慢38%,原因何在? size: function ...
- Redis慢链接查看
设置定义慢日志(小于n微秒的定义为慢日志):CONFIG SET slowlog-log-slower-than n 注:1秒 = 1,000,000微秒设置服务器保存的慢日志最多条数:config ...
- 在Javascript中onclick()方法应用
<html> < head> < script type="text/javascript"> function onclick1(){ ale ...
- 普林斯顿算法课第四周作业_8Puzzle
作业地址:http://coursera.cs.princeton.edu/algs4/assignments/8puzzle.html 作业难点: 1.如何求一个Puzzle的解? 根据作业提示,使 ...
- 【生活没有希望】hdu1166敌兵布阵 线段树
线段树水题刷刷,生活没有希望 最近看到代码跟树状数组差不多短的非递归线段树,常数也很小——zkw线段树 于是拿道水题练练手 短到让人身无可恋 ;pos;pos/=) a[pos]+=x;} ,ans= ...
- 区间DP LightOJ 1422 Halloween Costumes
http://lightoj.com/volume_showproblem.php?problem=1422 做的第一道区间DP的题目,试水. 参考解题报告: http://www.cnblogs.c ...