Android适配攻略
一、屏幕适配的必要性
为什么Android需要适配?
由于Android系统的开放性,任何用户、开发者、OEM厂商、运营商都可以对Android进行定制,修改成他们想要的样子。
但是这种“碎片化”到底到达什么程度呢?
在2012年,OpenSignalMaps(以下简称OSM)发布了第一份Android碎片化报告,统计数据表明,
2012年,支持Android的设备共有3997种。
2013年,支持Android的设备共有11868种。
2014年,支持Android的设备共有18796种。
随着Android系统的设备(手机、平板、电脑、手表)的增多,设备碎片化、品牌碎片化、系统碎片化、传感器碎片化和屏幕碎片化的程度也在不断地加深。Android设备的屏幕尺寸,从几寸的智能手机,到10寸的平板电脑,再到几十寸的数字电视,我们应该适配哪些设备?对于具有相同像素密度的设备来说,相像素越高,尺寸越大,从单纯的尺寸大小转换到像素大小和像素密度的角度来。
而对我们开发而言影响比较大的——屏幕碎片化
二、屏幕适配你所需要知道的
1,什么是屏幕尺寸?
屏幕尺寸:实际的物理尺寸,指屏幕的对角线的长度(单位inch-英寸)。
1英寸=2.54厘米。常见屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等。
四种屏幕尺寸分类:小(small),正常(normal),大(large),超大(xlarge)。
2,什么是屏幕分辨率?
屏幕分辨率:分为“图像分辨率”与“物理显示分辨率”;它们都是水平像素点数与垂直像素点数的乘积,也就是像素总和数。图像分辨率是指图片文件记录着自身所有的像素数。物理显示分辨率是指物理显示屏水平与垂直能显示的像素数的乘积。
指在横纵向上的像素点数,单位是px,1px=1个像素点。一般以纵向像素*横向像素,如1960*1080。
3,什么是屏幕像素密度dpi?屏幕密度的划分?
屏幕像素密度:指每英寸上的像素点数,点位dpi。
屏幕像素密度与屏幕尺寸和屏幕分辨率有关。在单一变化条件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。
标准是160dpi.即1dp=1个px,计算公式如:px = dp * (dpi / 160),屏幕密度越大,1dp对应的像素点越多。
不同设备有不同的显示效果,这个和设备硬件有关一般我们为了支持WVGA、HVGA和QVGA 推荐使用这 这个不依赖像素。
我们可以根据长或者根据宽来计算出dpi,计算公式为:
dpi=宽/((尺寸^2 * 宽^2)/(宽^2 + 高^2))^(1/2)
= 长/((尺寸^2 * 长^2)/(宽^2 + 高^2))^(1/2)
为简单起见, Android中的所有实际的屏幕密度分为六个广义密度:
低(ldpi),中(mdpi),高(hdpi),超高(xhdpi),超超高(xxhdpi),超超超高(xxxhdpi)。
屏幕像素密度越大图片显示就越清晰。
4,什么是屏幕方向?
从用户的角度看到的屏幕方向。一般为横向或纵向,即屏幕的宽高比。注意,不仅要关注不同的设备在缺省情况下的屏幕方向。同一设备当用户旋转时,应用程序的屏幕方向也需要关注。
5,Android系统的长度单位:
px(像素)——终端上的一个物理像素点,例如,480*800的屏幕在横向有320个象素,在纵向有480个象素。
像素注解:
一幅图片的显示就是由许多显示着不同颜色的小方格组成的,这样的小方格就被称为像素,是构成图片的最小单位。像素的具体大小取决于显示这张图片的具体的物理设备显示一个图片像素点的荧光点的大小.图片文件只是记录着它自身有多少个像素点,每个像素点显示什么颜色,至于它自身物理尺寸有多大,它自身也无法得知。
例如一张480*800像素的图片在电脑显示器上显示明显要比在手机屏幕上显示大很多,而这张图片本身并没有改变.只是手机的屏比电脑显示器的屏要精细许多,也就是每一个物理像素点要小许多,密度也 就大许多.
dip(dp)——这是Android开发中特有的一种度量,称作屏幕无关像素, 它不表示任何具体的长度或者像素点, 是一种基于屏幕密度抽象单位,被称作“设备独立像素”,会随着屏幕的密度进行自动的大小调整.
dp和px如何换算呢?在Android中,规定以160dpi为基准,1dip=1px,如果密度是320dpi, 则1dip=2px,以此类推。
sp——比例像素,与dp类似,可以根据文字大小首选项进行放缩,主要处理字体大小。
in:英寸,标准长度单位
mm:毫米,标准长度单位
pt:磅,标准长度单位,1/72英寸
dp和px转换公式:px = dp * (dpi / 160)
英寸和厘米之间的转换公式:1英寸=2.54厘米
下图是2014年初,友盟统计的占比5%以上的6个主流分辨率,可以看出,占比最高的是480*800,320*480的设备竟然也占据了很大比例,但是和半年前的数据相比较,中低分辨率(320*480、480*800)的比例在减少,而中高分辨率的比例则在不断地增加。虽然每个分辨率所占的比例在变化,但是总的趋势没变,还是这六种,只是分辨率在不断地提高。
所以说,我们只要尽量适配这几种分辨率,就可以在大部分的手机上正常运行了。
这几种分辨率分别是:1280x720 、1920x1080、854x480、800x480、960x540、480x320
不过一般情况下,我们适配两三套就可以了,除非遇到特殊情况的手机,就根据特殊情况来适配。
三、配置限定符
配置限定符的名称:
几乎每个应用程序应该提供替代的资源,以支持特定的设备配置。
1,创建一个新目录,在res/命名的形式<resources_name>-<config_qualifier>.
您可以附加多个<qualifier>。分隔每个替换为短划线。
谨慎:当追加多个限定符,你必须将它们放置在如下表 2 中列出的顺序相同。如果限定符是有错序,资源将被忽略。
表2:
附加:配置限定符名称
配置
限定符值
说明
MCC和MNC
例如: mcc310 mcc310-mnc004 mcc208-mnc00 等
MCC是移动国家代码的英文首字母缩写(The mobile country code),它的后面可选择性的跟随来自设备内的SIM卡的移动网络代码(MNC:mobile network code)。如在任何载体上,mcc310代表美国,mcc310-mnc004代表美国的Venizon公司,mcc208-mnc00代表法国的Orange公司。 如果设备使用音频连接(GSM 电话),那么MCC和MNC的值来自SIM卡。 也可以单独使用MCC(例如,在应用程序中包含特殊国家合法的资源)。如果仅需要指定语言环境,那么可以使用language和region限定符来替代(稍后讨论)。如果决定要使用MCC和MNC限定符,就要仔细测试,使它能够满足你所期望的工作。 还可以查看配置域mcc和mnc,它们分别指示了当前的移动国家代码和移动网络代码。 mcc:http://developer.android.com/reference/android/content/res/Configuration.html#mcc mnc:http://developer.android.com/reference/android/content/res/Configuration.html#mnc
语言和地区
例如: en fr en-rUS fr-rFR fr-rCA
语言是用两个字母的ISO 639-1语言代码定义的,紧跟其后的是可选的两个ISO-3166-1-appha-2地区代码字母(前面是小写的“r”)。 这个编码不区分大小写,r前缀被用于区分地区部分,不能够单独指定地区。 如果用户改变了系统中的语言设置,那么在应用程序的运行期间也能够改变为对应的语言。
最小宽度
swdp 例如: sw320dp sw600dp sw720dp 等
屏幕的基本尺寸,是指最短的可用屏幕区域。具体的说,设备的最小宽度是屏幕可用的宽度和高度中最短的那个(也可以把它看做是屏幕的最小可能的宽度)。这样就可以使用这个限定符来确保应用程序至少有dp的宽度可用于UI界面,而不管屏幕的当前方向。 例如,如果布局在任何时候都需要至少600dp的最小屏幕尺寸,那么就能够使用这个限定符,在res/layout-sw600dp/目录中创建布局资源。系统只会在可用屏幕的尺寸至少是600dp的时候才会使用这些资源,而不管600dp是否是被用户认知的高度或宽度。最小宽度是设备的固定屏幕尺寸特征,当屏幕的方向发生改变时,设备的最小宽度不改变。 设备的最小宽度需要考虑屏幕的装饰和系统UI的占用。例如,如果设备有一些固定的UI元素要沿着最小宽度的轴向,占用一定的屏幕空间,那么系统声明的最小宽度要比实际的屏幕尺寸要小,因为被系统占用的像素部分对用户应用程序的UI无效。因此,这个值应该是应用程序布局所需要的最小的实际尺寸(通常,这个值是布局支持的最小宽度,而不管屏幕的当前方向)。 以下是可以使用的通用屏幕尺寸的一些值: 1.320,针对以下屏幕配置的设备: 240x320ldpi(QVGA手持设备) 320x480mdpi(手持设备) 480x800hdpi(高分辨率手持设备) 2.480,针对480x800mdpi的屏幕(平板或手持设备) 3.600,针对600x1024mdip的屏幕(7英寸平板) 4.720,针对720x1280mdip的屏幕(10英寸平板) 当应用程序提供了多个带有不同值的最小宽度限定符资源目录时,系统会使用最接近(不超出)设备最小宽度的那个资源。 这个限定符被添加在API级别13中。 还要看android:requiresSmallestWidthDp属性,它声明了与你的应用程序兼容的最小的最小宽度,并且smallestScreenWidthDp配置字段会持有这个设备最小宽度的值。
可用宽度
wdp 例如: w720dp w1024dp 等
指定最小的可用屏幕宽度,在资源中应该以dp为单位来定义的值。当方向在横向和纵向之间改变时,这个配置值会跟当前的实际的宽度相匹配。 当应用程序给这个配置提供了多个不同值的资源目录时,系统会使用最接近(不超过)设备当前屏幕宽度的那个配置。这个值需要考虑屏幕装饰占据的空间,因此,如果设备在显示的左边或右边有一些固定的UI元素,那么使用的宽度值就要比实际的屏幕尺寸小,因为这些固定UI元素的占用,使得应用程序的可用空间减少。 这个特性被添加在API级别13中 还要看screenWidthDp配置字段,它持有当前的屏幕宽度。
可用高度
hdp 例如: h720dp h1024dp 等
指定最小的可用屏幕高度,在资源中应该以dp为单位来定义的值,当方向在横向和纵向直接改变时,这个配置值应该跟当前的实际高度匹配。 当应用程序给这个配置提供了不同值的多个资源目录时,系统会使用最接近(不超过)设备当前屏幕高度的那个配置。这个要考虑屏幕装饰的占用情况,因此,如果设备在显示的上方或底部有一些固定的UI元素,那么要使用的高度值要比实际的屏幕尺寸小,因为这些固定UI元素的占用,使得应用程序的可用空间减少。不固定的屏幕装饰(如电话的状态栏能够在全屏时被隐藏)是不考虑的,像标题栏或操作栏这样的窗口装饰也不考虑,因此应用必须准备处理比它们指定的空间要小的情况。 这个限定符被添加在API级别13中。 还要看screenHeightDp配置字段,它持有当前屏幕的高度。
屏幕尺寸
small normal large xlarge
small:这种屏类似低分辨率的QVGA屏幕。对于小屏的最小布局尺寸大约是320x426dp。例如QVGA低分辨率和VGA高分辨率。 normal:这种屏类似中等分辨率的HVGA屏幕。对于普通屏幕的最小布局尺寸大约是320x470dp。如,WQVGA低分辨率屏、HVGA中等分辨率屏、WVGA高分辨率屏。 large:这种屏类似中等分辨率的VGA屏幕,对于大屏幕的最小布局尺寸大约是480x640dp。例如VGA和WVGA的中等分辨率屏。 xlarge:这种屏被认为比传统的中等分辨率的HVGA屏幕大。针对xlarge屏的最小布局尺寸大约是720x960dp。在大多数情况下,这种超大屏幕的设备因为太大而要放到背包中来携带,而且最有可能的是平板样式的设备。 注意:使用尺寸限定符不意味着资源仅用于这个尺寸的屏幕。如果没有用限定符提供与当前设备配置相匹配的可选资源,那么系统会使用与配置最接近的资源。 警告:如果所有使用尺寸限定符的资源都比当前屏幕大,那么系统将不会使用它们,并且应用程序会在运行时崩溃(例如,如果所有的布局都被标记了xlarge限定符,而设备却是一个普通尺寸的屏幕)。 这个限定符被添加在API级别4以后的版本中。
屏幕外观
long notlong
long:长屏幕,如WQVGA、WVGA、FWVGA notlong:非长屏幕,如QVGA、HVGA、VGA 这个限定符被添加在API级别4以后的版本中 这个限定符完全是基于屏幕的外观比率,不相对屏幕的方向。 还要看screenLayout配置字段,它指示了屏幕是否是长屏。
屏幕方向
port land
port:纵向设备(垂直) land:横向设备(水平) 如果用户旋转屏幕,这个限定能够在应用程序运行期间改变。 orientation配置字段指示当前设备的方向。
泊位模式
car desk
car:设备停靠在汽车中 desk:设备停靠在书桌中 这个限定符被添加在API级别8以后的版本中 如果用户改变了设备的停靠地点,那么能够在应用程序的运行期间改变这个限定。可以使用UiModeManager对象来启用或禁止这种模式。
夜间模式
night notnight
night:夜间 notnight:白天 被添加在API级别8以后的版本中 如果夜间模式被保留在自动模式中(默认),那么在应用程序运行期间,会基于白天的时间来进行模式的改变。可以使用UiModeManager对象来启用或禁止这种模式。
屏幕像素密度(dpi)
ldpi mdpi hdpi xhdpi nodpi tvdpi
ldpi:针对大约120dpi的低分辨率屏幕; mdpi:针对大约160dpi的中等分辨率屏幕(在传统的HVGA上); hdpi:针对大约240dpi的高分辨率屏幕; xhdpi:针对大约320dpi的超高分辨率屏幕,被添加在API基本8以后的版本中; nodpi:这个限定被用于不想根据匹配的设备分辨率进行缩放的位图资源。 tvdpi:在mdpi和hdpi之间的屏幕,大约是213dpi。这种分组不是主要的分辨率,大多数是为电视来考虑的,并且大多数应用不需要它---提供mdpi和hdpi资源就可以满足大多数应用程序需要了,并且系统会适当的缩放它们。这个限定符在API级别13以后被引入。 四种主要的分辨率之间的缩放比例是:3:4:6:8(忽略tvdpi分辨率),因此一个9x9的ldpi位图,在mdpi中是12x12、在hdpi中是18x18、在xhdpi中是24x24。 如果感觉在电视或其他某些设备上的图片资源不好看,并且想要试用tvdpi资源,那么缩放因子是1.33*mdpi。例如,一个100px x 100px的mdpi图片的图片应该被放大成133px x 133px的tvdpi图片。 注意:使用分辨率限定符不意味着资源仅适用与对应分辨率的屏幕。如果没有提供与当前设备配置匹配的可选资源,那么系统会使用最接近的资源。
触屏类型
notouch stylus finger
notouch:非触屏设备 stylus:有适用手写笔的电阻屏设备 finger:触屏设备 touchscreen配置字段,指示到了设备上的触屏类型。
键盘可用性
keysexposed keyshidden keyssoft
keysexposed:设备有可用的键盘。如果设备启用了软键盘,那么即使在硬键盘没有暴露给用户时也可以使用这个限定符。如果没有提供软键盘或者软键盘被禁用,那么只有在硬键盘被暴露给用户时才能够使用这个限定符。 keyshidden:设备有可用的硬键盘,但是被隐藏了,并且设备没有可用的软键盘。 keyssoft:设备有可用的软键盘,不管它是否可见。 如果提供了keysexposed资源,但没有keyssoft资源,那么只要系统有可用的软键盘,系统就会使用keysexposed资源而不管键盘是否可见。 如果用户打开了硬键盘,就可以在应用程序运行期间改变这个限定。 hardKeyboardHidden和keyboardHidden配置字段分别指明硬键盘的可见性以及可见的键盘类型(包括软键盘)。
主要文本输入法
nokeys qwerty l2key
nokeys:设备没有用于文本输入的硬键盘; qwerty:设备有标准的硬键盘,不管用户是否可见; 12key:设备有12个键的硬键盘,不管用户是否可见。 keyboard配置字段指明可用的主要文本输入方法。
导航键的有效性
navexposed navhidden
navexposed:导航键对用户可用; navhidden:导航键不可用。 如果用户能够看到导航键,那么在应用程序运行时就能够改变这个限定。 navigationHidden配置字段,指示导航键是否隐藏。
主要的非触屏导航方法
nonav dpad trackball wheel
nonav:除了使用触屏以外,设备没有其他导航设施。 dpad:设备有用于导航的定向板(d-pad)。 trackball:设备有用于导航的轨迹球 wheel:设备有用于导航的定向滚轮(不常见)。 navigation配置字段指明可用的导航方法类型。
平台版本(API 级别)
例如: v3 v4 v7 等
设备支持的API级别。如v1代表API级别1(带有Android1.0或更高版的设备),v4代表API级别4(带有Android1.6或更高版本的设备) 警告:Android1.5和1.6只有在限定符跟平台版本完全匹配时,才能匹配资源
以上所写的限定符只是简单介绍,主要是为了得知限定符的顺序,要看完整列表,请到官网限定符url:http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources
2,在这新的目录中保存各自的替代资源。资源文件必须命名的默认资源文件完全相同。
Android 支持几个配置限定符,你可以将多个限定符添加到一个目录名称,通过用短划线分隔每个限定符。按优先级顺序 — — 如果你使用多个限定符资源目录,你必须将他们添加到表中列出的顺序中的目录名称。
3,配置限定符的名称列表,
(1)配置:MCC和跨国公司
限定符值:如mcc310(是美国在任何载体上)、mcc310-mnc004(是美国Verizon)、mcc208-mnc00(是法国上橙色)等;
(2)配置:语言和区域
限定符值:如en、fr、rn-rUS、fr-rFR、fr-rCA等;
(3)配置:布局方向:你的应用程序布局方向
限定符值:
ldrtl “布局-方向-右到左”如文件名:res/layout/layout-ldrtl/
ldltr “布局-方向-左到右”如文件名:res/layout/layout-ldltr/
注:若要为您的应用程序启用从右向左布局功能,必须将supportsRtl设置为"true" ,并将targetSdkVersion设置为 17 或更高。
(4)配置:smallestWidth——基本大小的保障,可用的屏幕区域的最短尺寸所示
限定符值:sw320dp、sw600dp、sw720dp等
例如,如果您的布局要求,其最小尺寸的屏幕区域至少 600 dp 在任何时候,然后你可以使用这个 qualifer 创建布局资源, res/layout-sw600dp/。系统将使用这些资源时,才可用屏幕的最小尺寸至少 600dp,无论 600dp 侧是用户感知的高度或宽度。SmallestWidth 是设备的一个固定的屏幕大小特征;设备的 smallestWidth 不会更改屏幕方向更改时.
(5)配置:可用宽度——指定最小的可用屏幕宽度, dp单位应使用资源 — — 由<N>值定义。
此配置值会改变方向之间横向和纵向以匹配当前的实际宽度发生变化时。
限定符值:w720dp、w1024dp等
(6)配置:可用高度——最低可用的屏幕高度,指定应该使用该资源的"dp"单位 — — 由<N>值定义。
此配置值会改变方向之间横向和纵向以匹配当前的实际高度发生变化时。
限定符值:h720dp、h1024dp等
(7)配置:屏幕大小
限定符值:
small : 到低密度的 QVGA 屏幕大小相似的屏幕。
normal :中等密度 HVGA 屏幕大小相似的屏幕。
large :中等密度 VGA 屏幕大小相似的屏幕。
xlarge :大大大于传统介质密度 HVGA 屏幕的屏幕
(8)配置:圆形屏幕
限定符值:
round 圆如圆可穿戴设备的屏幕
notround 矩形屏幕,如手机或平板电脑
(9)配置:屏幕方向
限定符值:
port 设备是纵向 (垂直)
land 设备是横向 (水平)
(10)配置:用户界面模式
限定符值:
car 把车停靠在展示设备
desk 设备显示在一个桌子上码头
television 设备显示在电视上提供其 UI 在哪里用户距离遥远的大屏幕的"十脚"经验,
主要围绕 DPAD 或其他非指针交互。
appliance 设备服务作为一种装置,与无显示
watch 设备具有显示和戴在手腕上
(11)配置:夜间模式
限定符值:
night 晚上的时间
notnight 一天时间
(12)配置:屏幕像素密度
限定符值:
ldpi 低密度屏幕;大约 120 dpi。
mdpi 中等密度 (在传统的 HVGA) 屏幕;大约 160 dpi
hdpi 高密度屏幕;大约 240 dpi
xhdpi Extra-high-density 屏幕;大约 320 dpi。添加在 API 级别 8
xxhdpi 外超高密度屏幕;大约 480 dpi。添加在 API 级别 16
xxxhdpi 超-超额外--高密度用途 (启动器图标,只见在支持多屏幕的注意);大约 640 dpi。添加在 API 级别 18
nodpi 这可以用于你不想要缩放,以匹配设备密度的位图资源
tvdpi 屏幕介于 mdpi 和下;约 213 dpi。这不是"主"密度组。它主要用于电视机和大多数应用程序不应该需要它。
(13)配置:触摸屏类型
限定符值:
notouch 设备没有触摸屏
finger 设备已打算用于通过用户的手指的双向互动的触摸屏。此外看到touchscreen配置字段,
指示设备上的触摸屏的类型。
(14)配置:键盘可用性
限定符值:
keysexposed 设备有可用的键盘。
keyshidden 设备具有可用的硬件键盘,但它是隐藏和设备不启用软件键盘。
keyssoft 设备已启用,软件键盘是否可见。
(15)配置:主要文本输入法
限定符值:
nokeys 设备有没有硬件键进行文本输入。
qwerty 设备具有一个硬件 qwerty 键盘,是否对用户可见。
12key 设备具有硬件 12 键键盘,是否对用户可见。
(16)配置:导航关键可用性
限定符值:
navexposed 导航键是提供给用户。
navhidden 导航键不可用 (如背后密封盖子)。
(17)配置:主的非接触式导航方法
限定符值:
nonav 设备有没有使用触摸屏的导航设施。
dpad 设备具有定向垫 (d-垫) 为导航
trackball 设备已用于导航的轨迹球
wheel 设备已用于导航 (罕见) 定向 (第)。
(18)配置:平台版本(API级别)
限定符值:v3、v4、v7等。
4,限定符命名规则:
(1)可以指定一组资源,以短划线分隔的多个限定符;
(2)限定符必须在表 2中列出的顺序。例如:
错误:drawable-hdpi-port/
正确:drawable-port-hdpi/
(3)不能嵌套替代资源目录。例如,您不能有res/drawable/drawable-en/.
(4)值不区分大小写。资源编译器前处理,以避免在不区分大小写的文件系统上的问题,将目录名称转换为小写字母。
名称中的任何大写只是受益的可读性。
(5)支持每个限定符类型只有一个值。例如,如果您想要使用相同的可绘制文件为西班牙和法国,你不能有一个名为
目录drawable-rES-rFR/。相反你需要两个资源目录,如drawable-rES/和drawable-rFR/,其中包含相应的文件。
5,下面是用常见的一些类型的手机总结的一个表格,可以简单做一下参考:
四、屏幕的分类
1)以总像素数分,文本的size等都要改,如下图所示:
每一个分类都有其最小分辨率,如下,可根据分辨率划分种类:
2)以屏幕密度分,提供不同的图片,如下图所示:
五、屏幕的适配
掌握了以上的知识,我们现在开始来对Android进行屏幕适配:
Android的多屏幕支持的基础是它能够根据当前屏幕配置以适当的方式管理提出申请的布局和位图渲染能力。
系统处理的大部分工作是以适应屏幕尺寸/密度缩放布局和扩展位图以适应屏幕像素密度。
你应该确信你应用程序布局:
适合在小屏幕 (这样用户实际上可以使用您的应用程序);
为更大的屏幕,以利用额外的屏幕空间优化;
针对横向和纵向方向优化。
1,在manifest中显示声明应用程序支持的屏幕尺寸清单
设置多分辨率支持,代码如下所示:
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:resizeable="true"
android:smallScreens="true" />
注解:
android:anyDensity="true",系统会依据屏幕密度,自动去找对应的文件夹
android:requiresSmallestWidthDp
android:compatibleWidthLimitDp
android:largestWidthLimitDp
以上这三个属性也是写在supports-screens中,但我们一般不用它,这里就不多做解释了,若想要了解详情请查看链接:http://developer.android.com/guide/practices/screens_support.html
2,图片适配
为不同的屏幕密度提供不同的位图画板。不同像素密度的手机加载工程资源文件(res)中不同资源图片。Android有个自动匹配机制去选择对应的布局和图片资源
从Android 1.6 ( API 4 )开始, Android提供了多种屏幕尺寸和密度,反映了多种不同的设备可能支持屏幕配置。
Android把实际的屏幕尺寸和密度分成如下范围:
官方指定标准:
虽然Android也支持低像素密度(LDPI)的屏幕,但无需为此费神,系统将自动将HDPI尺寸的图标缩小到1/2进行匹配。
比如下面就是一些在各个屏幕密度里面的尺寸:
按照以上计算方式,大致可以将市场上的手机划分为5个像素密度等级,具体如下:
(1) ldpi:120dpi,像素密度与dp转换关系为:1dp = 0.75px
(2) mdpi:160dpi ,像素密度与dp转换关系为:1dp = 1px
(3) hdpi:240dpi,像素密度与dp转换关系为:1dp = 1.5px
(4) xhdpi:320dpi,像素密度与dp转换关系为:1dp = 2px
(5) xxhdpi:480dpi,像素密度与dp转换关系为:1dp = 3px
我们可使用屏幕像素密度限定符来创建不同的图片文件夹,如下图所示:
注意:上图各种文件夹的不同表示。
drawable-hdpi 该图片即适用于横屏,也适用于竖屏
drawable-land-hdpi,当屏幕为横屏,且为高密度时,加载此文件夹中的资源
drawable-port-hdpi,当屏幕为竖屏,且为高密度时,加载此文件夹中的资源
ldpi、mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi:像素密度比例缩放为1:2:3:4:6:8
在有关图片的适配时,我们需要把合适大小的图片放在合适的位置,如下图所示:
支持多个屏幕的目的是创建一个应用程序可以正常工作,可以在任何支持的安卓系统的广义的屏配置看起来不错。
关于高清设计图尺寸
Google官方给出的高清设计图尺寸有两种方案,一种是以mdpi设计,然后对应放大得到更高分辨率的图片,另外一种则是以高分辨率作为设计大小,然后按照倍数对应缩小到小分辨率的图片。据经验,我更推荐第二种方法,因为小分辨率在生成高分辨率图片的时候,会出现像素丢失,我不知道是不是有方法可以阻止这种情况发生。
而分辨率可以以1280*720或者是1960*1080作为主要分辨率进行设计。
Android 寻找最佳资源原理:
1, 排除与设备设置不符合的资源
2, 根据限定词(qualifier)的优先级,按照顺序查找
3, 在限定词下,是否存在资源路径
4, 排除不包含在限定词中的资源路径
5, 继续执行不同的限定词查找,直到找到相应的资源
详细解释:
(1)首先会去比自己密度高的目录里去找,这是因为因为系统相信,你在密度更高的目录里会放置分辨率更
大的图片,这样的话这个图片会被缩小,但同时显示效果不会有损失,但是如果优先去低一级别的目录去找的话,找到的图片就会被放大,这样的话这个图片就会被拉扯模糊了。
e.g. 同一张图片,你在mdpi和xxhdpi目录各放了一份, 这个应用你现在运行在hdpi的手机上, 那应用会选择哪张图片呢。答案是xxhdpi目录里的。即便hdpi离mdpi更近一点!
(2)如果在mdpi里找不到是不会直接去ldpi里找的, 而是先去默认的drawble目录里找,这是drawble目录
和drawble-mdpi是一个级别的。
(3)如果drawable-hdpi,drawable-mdpi,drawable-ldpi三个文件夹中有同一张图片资源的不同密度表示,
那么系统会去加载drawable_mdpi文件夹中的资源。
(4)如果drawable-hpdi中有高密度图片,其它两个文件夹中没有对应图片资源,那么系统会去加载
drawable-hdpi中的资源。
(5)如果drawable-hdpi,drawable-mdpi中有图片资源,drawable-ldpi中没有对应的图片资源,
那么系统会加载drawable-mdpi文件夹中的资源 。
3,布局文件适配
为不同的屏幕尺寸提供不同的布局。
根据配置限定符,你可以用它来提供大小的特定资源,比如小,正常,大和超大 。
例如,超大屏幕布局应该在文件夹layout-xlarge /下面 。
从Android 3.2 ( API等级13 )起,上述尺寸组已过时,应改用sw dp配置限定符来定义你的布局资源所需的最小可用宽度。例如,如果你的平板电脑的布局至少需要600dp屏幕宽度,你应该把它放在文件夹layout-sw600dp /下 。在有关平板布局的声明在Android 3.2节进一步讨论。
布局可以使用的限定符是:
smallestWidth——基本大小的保障,可用的屏幕区域的最短尺寸所示:
sw320dp、sw600dp、sw720dp等
屏幕大小:small、normal、large、xlarge
屏幕方向:port(垂直)、land(水平)
实际的物理尺寸,指屏幕的对角线的长度(单位inch-英寸)。
1英寸=2.54厘米。常见屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等
可创建的layout:若有layout-normal和layout-1920x12080的话,会执行layout-normal,
下面是布局layout根据限定配置符所创建的文件:
注意:里面的布局文件名相同,文件里面的控件id也是相同
对于最小宽度大于等于 600 dp 的设备,系统会选择 layout-sw600dp/main.xml(双面板)布局,否则系统就会选择 layout/main.xml(单面板)布局。
但 Android 版本低于 3.2 的设备不支持此技术,原因是这些设备无法将 sw600dp 识别为尺寸限定符,因此我们仍需使用 large 限定符。这样一来,就会有一个名称为 res/layout-large/main.xml 的文件(与 res/layout-sw600dp/main.xml 一样)
注意:可以查询一下API所对应的版本,13代表的是3.2版本
注意:当你使用多个限定符时要按照限定符顺序,否则,资源将被忽略。
这里是关于如何你可以确保您的应用程序在不同的屏幕上显示正确的快速清单:
(1)不要使用绝对布局
(2)尽量使用match_parent 而不是fill_parent 。
(3)能够使用权重的地方尽量使用权重(android:layout_weight)
(4)如果是纯色背景,尽量使用android的shape 自定义。
(5)如果需要在特定分辨率下适配,可以在res目录上新建layout-HxW.xml的文件夹。比如要适配1080*1800的屏幕(魅族MX3采用此分辨率)则新建layout-1800x1080.xml的文件夹,然后在下面定义布局。Android系统会优先查找分辨率相同的布局,如果不存在则换使用默认的layout下的布局。
(6)ImageView的ScaleType属性
设置不同的ScaleType会得到不同的显示效果,一般情况下,设置为centerCrop能获得较好的适配效果。
注意:
使用 “wrap_content”,系统就会将视图的宽度或高度设置成所需的最小尺寸以适应视图中的内容,而 “match_parent”(在低于 API 级别 8 的级别中称为 “fill_parent”)则会展开组件以匹配其父视图的尺寸。如果使用 “wrap_content” 和 “match_parent” 尺寸值而不是硬编码的尺寸,视图就会相应地仅使用自身所需的空间或展开以
填满可用空间。此方法可让布局正确适应各种屏幕尺寸和屏幕方向。
示例代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.student.android_screenadaptation.MainActivity" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=" 为了屏幕的多适配,我们可以要多用
match_parent或wrap_content,以及下面布局
中的线性布局的android:layout_weight属性," />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2.0"
android:background="@color/gw_dark_orange"
android:gravity="center"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这边占用了2份" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:background="@color/gw_default_blue"
android:gravity="center"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这边占用了1份" />
</LinearLayout>
</LinearLayout>
显示的效果:
在开发中,我们大部分时候使用的都是线性布局、相对布局和帧布局,绝对布局由于适配性极差,所以极少使用。
3,dimens.xml文件适配
Value所创建的文件夹及文件如下所示:
具体情况就不说了,下面的这个博客链接里面讲解的很清楚,大家可以参考:
http://blog.csdn.net/lmj623565791/article/details/45460089
4,java代码适配
通过android相应api获取当前手机的宽高像素值,按比例分配屏幕中控件的宽高以达到适配效果。
下面是布局和实现功能的核心代码:
获取屏幕尺寸:
/* 定义DisplayMetrics对象 */
DisplayMetrics dm = new DisplayMetrics();
/* 取得窗口属性 */
getWindowManager().getDefaultDisplay().getMetrics(dm);
/* 窗口的宽度 */
int screenWidth = dm.widthPixels;
/* 窗口的高度 */
int screenHeight = dm.heightPixels;
Android全屏显示、横竖屏设置:
一般程序在运行时屏幕顶部都带有标题栏和系统信息栏
但在游戏开发时为了美观,我们就需要全屏显示:
通过requestWidowFeature方法可以设置标题栏是否显示,通过setFlags方法可以设置全屏模式
通过setRequestedOrientation方法将显示模式设置为横屏模式。
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* 设置为无标题栏 */
requestWindowFeature(Window.FEATURE_NO_TITLE);
/* 设置为全屏模式 */
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
/* 设置为横屏 */
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.main);
}
Android屏幕适配项目模板下载地址:https://git.oschina.net/22889/Android_ScreenSmartScale.git
仅供参考,如果您有更好的方法,欢迎讨论,欢迎分享