现在手机的类型非常之多,在开发的时候,如果想要适配不同的手机,则需要考虑我们的应用如何适配不同的屏幕。当然,工如善其事,必先得其器。首先,我们需要了解安卓手机中的一些基本单位,便于我们后面更好的讨论如何适配,以及其适配的根本原理。
分辨率是一个更重要的概念,是相对于软件设计而言的,对于我们做不同分辨下的手机适配非常重要,下面是百科的定义,关于更加详细的说明,请看百科。
这些术语都是指屏幕的分辨率。
VGA:Video Graphics Array,即:显示绘图矩阵,相当于640×480 像素;
HVGA:Half-size VGA;即:VGA的一半,分辨率为480×320;
QVGA:Quarter VGA;即:VGA的四分之一,分辨率为320×240;
WVGA:Wide Video Graphics Array;即:扩大的VGA,分辨率为800×480像素;
WQVGA:Wide Quarter VGA;即:扩大的QVGA,分辨率比QVGA高,比VGA低,一般是:400×240,480×272;
分辨率是屏幕图像的精密度,是指显示器所能显示的像素的多少。由于屏幕上的点、线和面都是由像素组成的,显示器可显示的像素越多,画面就越精细,同样的屏幕区域内能显示的信息也越多,所以分辨率是个非常重要的性能指标之一。可以把整个图像想象成是一个大型的棋盘,而分辨率的表示方式就是所有经线和纬线交叉点的数目。
我想上面列出其英文意思,是更好理解和记忆对应分辨率的来源吧。(都是以VGA为base);
目前对于手机的大小的描述,消费者更多的关注两个点,其实更多的是一个点,就是物理大小,即多少寸。可能在行一点的,会考虑分辨率的问题。说到分辨率,可能大家都还是不太了解,其实分辨率与手机物理大小无关。即手机物理大小与手机分辨率没有直接的关系。
在同一种尺寸大小的手机上,分辨率越高,画面会越细腻。画面的细节越多(说明白点,就是会更加清晰。)
下面看一下其他单位的含义
px:(pixels)(像素):屏幕上的点,与密度相关。密度大了,单位面积上的px会比较多。表示屏幕实际的象素。例如,320*480的屏幕在横向有320个象素,在纵向有480个象素。
dip或dp(与密度无关的像素)。这个和设备硬件有关,为了支持WVGA、HVGA和QVGA 5进制空间推荐使用这个。一种基于屏幕密度的抽象单位。设置一些view的宽高可以用这个,一般情况下,在不同分辨率,都不会有缩放的感觉。如果用px的话,320px占满HVGA的宽度,到WVGA上就只能占一半不到的屏幕了,那一定不是你想要的。
sp(与刻度无关的像素)放大像素– 主要处理字体的大小。
in:表示英寸,是屏幕的物理尺寸。每英寸等于2.54厘米。例如,形容手机屏幕大小,经常说,3.2(英)寸、3.5(英)寸、4(英)寸就是指这个单位。这些尺寸是屏幕的对角线长度。如果手机的屏幕是3.2英寸,表示手机的屏幕(可视区域)对角线长度是3.2*2.54 = 8.128厘米。读者可以去量一量自己的手机屏幕,看和实际的尺寸是否一致。
mm:表示毫米,是屏幕的物理尺寸。
pt:表示一个点,是屏幕的一个物理长度,大小为1英寸的1/72。
换算公式:
px = (density/160)dp
density一般为3个常用固定值240/160/120。分别对应WVGA/HVGA/QVGA。其中density值表示每英寸有多少个显示点,与分辨率是两个概念。
了解了以上的概念,我们现在谈谈具体的适配问题了。
首先关于适配,说一些比较实用的经验,对于不想深入了解,又想能够很好的解决适配的问题,是个不错的选择,但我还是很建议花一些时间真正了解原理,这样遇到什么问题,都不在话下了。
1、尽量使用比例控制适配。例如weight这个属性。(这个是按屏幕的大小比例来进行适配的)
但是这个方法非常局限,1是因为你的应用不可能都是通过比例的方式来进行布局的。第二是这种比例方法是适用于linerLayout里面的比例适配。
2、多使用相对布局,而不是绝对布局。
我想做网页前台设计的朋友我也类似的体会,对于不同分辨率的电脑,使用相对布局,根据相对位置来决定,跟分辨率无关。和第一条的经验的原理差不多。例如还有fill_parent,match_parent,wrap_content等。
3、尽量使用dp而不是px
由pixs = (density/160)*dpis 换算公式可知,这样适配的时候不会受屏幕density的影响,但并不是绝对百分百适用。
4、使用9.PNG(九宫格图片)的方式来进行不同背景的适配。(参考博文http://blog.csdn.net/ouyang_peng/article/details/9242889)自认为比较详细。主要是适配内容的变化,保证四个用能够进行适配。
5、通过qulifier修饰方式来来指定不同的适配方案。
这个也是android适配最根本的解决方案。即根据不同的设备提供不同的适配方案。理所当然能够满足所有需求,只是工作量会比较大,而且配置也会有一些麻烦,但这绝对是根本的解决方法。
首先在了解这种适配方案之前,我们先要了解,google在对不同的屏幕适配所做的一些设计。当然首先你得有前面的一些基本概念。
一、android多屏幕支持机制
Android的支持多屏幕机制即用为当前设备屏幕提供一种合适的方式来共同管理并解析应用资源。
Android平台中支持一系列你所提供的指定大小(size-specific),指定密度(density-specific)的合适资源。
指定大小(size-specific)的合适资源是指small, normal, large, and xlarge。
指定密度(density-specific)的合适资源,是指ldpi (low), mdpi (medium), hdpi(high), and xhdpi (extra high).
Android有个自动匹配机制去选择对应的布局和图片资源
1)界面布局方面
根据物理尺寸的大小准备5套布局:
layout(放一些通用布局xml文件,比如界面顶部和底部的布局,不会随着屏幕大小变化,类似windos窗口的titlebar),
layout-small(屏幕尺寸小于3英寸左右的布局),
layout-normal(屏幕尺寸小于4.5英寸左右),
layout-large(4英寸-7英寸之间),
layout-xlarge(7-10英寸之间)
2)图片资源方面
需要根据dpi值准备5套图片资源:
drawable:主要放置xml配置文件或者对分辨率要求较低的图片
drawalbe-ldpi:低分辨率的图片,如QVGA (240x320)
drawable-mdpi:中等分辨率的图片,如HVGA (320x480)
drawable-hdpi:高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
drawable-xhdpi:至少960dp x 720dp
Android有个自动匹配机制去选择对应的布局和图片资源。
系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。
在开发程序时为了兼容不同平台不同屏幕,建议各自文件夹根据需求均存放不同版本图片。
二、AndroidManifest.xml 配置
ndroid从1.6和更高,Google为了方便开发者对于各种分辨率机型的移植而增加了自动适配的功能
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true"/>
3.1是否支持多种不同密度的屏幕
android:anyDensity=["true" | "false"]
如果android:anyDensity="true"
指应用程序支持不同密度,会根据屏幕的分辨率自动去匹配。
如果android:anyDensity="false"
应用程序支持不同密度,系统自动缩放图片尺寸和这个图片的坐标。具体解释一下系统是如何自动缩放资源的。
例如我们在hdpi,mdpi,ldpi文件夹下拥有同一种资源,那么应用也不会自动地去相应文件夹下寻找资源,这种情况都是出现在高密度,以及低密度的手机上,比如说一部240×320像素的手机,
如果设置android:anyDensity="false",Android系统会将240 x320(低密度)转换为320×480(中密度),这样的话,应用就会在小密度手机上加载mdpi文件中的资源。
3.2是否支持大屏幕
android:largeScreens=["true" | "false"]
如果在声明不支持的大屏幕,而这个屏幕尺寸是larger的话,系统使用尺寸为("normal")和密度为("medium)显示,
不过会出现一层黑色的背景。
3.3是否支持小屏幕
android:smallScreens=["true" | "false"]
如果在声明不支持的小屏幕,而当前屏幕尺寸是smaller的话,系统也使用尺寸为("normal")和密度为("medium)显示
如果应用程序能在小屏幕上正确缩放(最低是small尺寸或最小宽度320dp),那就不需要用到本属性。否则,就应该为最小屏幕宽度标识符设置本属性
来匹配应用程序所需的最小尺寸。
三、Android提供3种方式处理屏幕自适应
4.1预缩放的资源(基于尺寸和密度去寻找图片)
1)如果找到相应的尺寸和密度,则利用这些图片进行无缩放显示。
2)如果没法找到相应的尺寸,而找到密度,则认为该图片尺寸为 "medium",利用缩放显示这个图片。
3)如果都无法匹配,则使用默认图片进行缩放显示。默认图片默认标配 "medium" (160)。
4.2自动缩放的像素尺寸和坐标(密度兼容)
1)如果应用程序不支持不同密度android:anyDensity="false",系统自动缩放图片尺寸和这个图片的坐标。
2)对于预缩放的资源,当android:anyDensity="false",也不生效。
3)android:anyDensity="false",只对密度兼容起作用,尺寸兼容没效果
4.3兼容更大的屏幕和尺寸(尺寸兼容)
1)对于你在声明不支持的大屏幕,而这个屏幕尺寸是normal的话,系统使用尺寸为 ("normal")和密度为("medium)显示。
2.)对于你在声明不支持的大屏幕,而这个屏幕尺寸是larger的话,系统同样使用尺寸为("normal")和密度为("medium)显示,
不过会出现一层黑色的背景。
四、代码相关
在代码中获取屏幕像素、屏幕密度
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕宽度(像素)
int height = metric.heightPixels; //屏幕高度(像素)
float density = metric.density; // 屏幕密度(0.75 /1.0 / 1.5)
int densityDpi = metric.densityDpi; //屏幕密度DPI(120 / 160 /240)