对于从事android应用开发的朋友来说都应该知道,现在的安卓手机的屏幕类型十分繁多, 大小尺寸,长宽比例都不尽相同,同一个界面在不同分辨率的手机上可能出现布局错乱,控件跑位的现象。做屏幕的适配不可能实现在每种屏幕上显示出的界面 效果完全一致。只能靠平时的编程习惯和经验是的界面在不同的屏幕尺寸在不会出现过分的走位,在可遇见范围内控制界面在不同屏幕下的变化,并做出相应调 整。那么偶们应该如何做到屏幕的适配呢?下面我就以我的开发经验来说说吧。
1、尽量使用线性布局(LinearLayout)和相对布局(RelativeLayout),不要使用绝对布局。
2、尽量使用dip和sp,不要使用px。
3、为不同的分辨率提供不同的布局文件和图片。
4、在AndroidMainfest.xml中设置多分辨率支持。
Android屏幕适配必须要理解的一些概念:
- px
是英文单词pixel的缩写,意为像素,屏幕上的点。我们通常所说的分辨率如480X800就是指的像素。
在设计领域中,像素是用来计算数码影像的最小单位。计算机中显示的图像并非连续的线条组成,而是由许多肉眼看不见的小点组成。如果把影像放大数倍,会发现这些连续色调其实是由许多色彩相近的小点所组成,这些小点就是构成影像的最小单位“像素”。
- in
表示英寸,是屏幕的物理尺寸。每英寸等于2.54厘米。例如我们经常说的手机屏幕大小有,5(英)寸、4(英)寸就是指这个单位。这些尺寸是屏幕的对角线长度。如果手机的屏幕是4英寸,表示手机的屏幕(可视区域)对角线长度是4 X 2.54 = 10.16厘米。
- dpi
dpi是Dots Per Inch的缩写, 每英寸点数,即每英寸包含像素个数。比如320X480分辨率的手机,宽2英寸,高3英寸, 每英寸包含的像素点的数量为320/2=160dpi(横向)或480/3=160dpi(纵向),160就是这部手机的dpi,横向和纵向的这个值都是相同的,原因是大部分手机屏幕使用正方形的像素点。
- density
屏幕密度,density和dpi的关系为 density = dpi/160
- dp
也即dip,设备独立像素,device independent pixels的缩写,Android特有的单位,在屏幕密度dpi = 160屏幕上,1dp = 1px。
- sp
和dp很类似,一般用来设置字体大小,和dp的区别是它可以根据用户的字体大小偏好来缩放。
layout_weight属性
这个属性其实很好用,一般和android:layout_height="fill_parent"或 android:layout_width="fill_parent"一起使用,它用于描述该子元素在剩余空间中占有的大小比例。加入一行只有一个文本 框,那么它的默认值就为0,如果一行中有两个等长的文本框,那么他们的android:layout_weight值可以是同为1。如果一行中有两个不等 长的文本框,那么他们的android:layout_weight值分别为1和2,那么第一个文本框将占据剩余空间的三分之二,第二个文本框将占据剩余 空间中的三分之一。android:layout_weight遵循数值越小,重要度越高的原则。android屏幕如此繁多,不可能都是等比例缩放的, 所以单纯使用dip来设置控件也是行不通,与layout_weight属性灵活结合使用,增强界面的适应性。
drawable资源
首先:你需要在AndroidManifest.xml文件的元素如下添加子元素
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true" />
名如其意,以上是为我们的屏幕设置多分辨率支持(更准确的说是适配大、中、小三种密度)。android:anyDensity="true" ,这一句对 整个的屏幕都起着十分重要的作用,值为true,我们的应用程序当安装在不同密度的手机上时,程序会分别加载hdpi,mdpi,ldpi文件夹中的资 源。相反,如果值设置为false,即使我们在hdpi,mdpi,ldpi文件夹下拥有同一种资源,那么应用也不会自动地去相应文件夹下寻找资源,这种 情况都是出现在高密度,以及低密度的手机上,比如说一部240×320像素的手机,如果设置 android:anyDensity="false",Android系统会将240 x 320(低密度)转换为 320×480(中密度),这样的 话,应用就会在小密度手机上加载mdpi文件中的资源。
细心的人会发现自 android2.0开始之后drawable文件被三个文件夹drawable-hdpi,drawable-mdpi,drawable-ldpi三 个文件夹所取代,有些编程人员为了让应用程序默认地加载某些图片,他们会特意地去在android2.0之后的应用程序中重新创建drawable文件 夹,其实这样做完全没有必要,通过第一段的分析我们得知,android:anyDensity="false",则应用会将大小密度转变成中密度,从而 去加载mdpi中的资源。这里同样,当android:anyDensity="false",则应用会去加载mdpi中的资源。
总结一下:
第一:android:anyDensity="true",系统会依据屏幕密度,自动去找对应的文件夹
第二:android:anyDensity="false",
(1)如果drawable-hdpi,drawable-mdpi,drawable-ldpi三个文件夹中有同一张图片资源的不同密度表示,那么系统会去加载
drawable_mdpi文件夹中的资源
(2)如果drawable-hpdi中有高密度图片,其它两个文件夹中没有对应图片资源,那么系统会去加载drawable-hdpi中的资源。
(3)如果drawable-hdpi,drawable-mdpi中有图片资源,drawable-ldpi中没有对应的图片资源,那么系统会加载drawable-mdpi文件夹中的资源
注意上图各种文件夹的不同表示。
drawable-hdpi 该图片即适用于横屏,也适用于竖屏
drawable-land-hdpi,当屏幕为横屏,且为高密度时,加载此文件夹中的资源
drawable-port-hdpi,当屏幕为竖屏,且为高密度时,加载此文件夹中的资源
draw9patch工具
android SDK 包的tools目录下为偶们提供了这么一个图片处理工具。有时候偶们需要图片资源自适应且不失真,无论横屏还是竖屏,高分辨率还是低分辨率,都能自动填充 满,而且不失真等等背景问题。 Android针对这种情况,专门制作了一种.9.PNG格式来解决这个问题。draw9patch就是帮助偶们制 作.9.PNG格式资源的一个小工具。
*.9.PNG就标准的PNG格式,只是在最外面一 圈额外增加1px的边框,这个1px的边框就是用来定义图片中可扩展的和静态不变的区域。特别说明,left(左)和top(上)边框中交叉部分是可拉伸 部分,未选中部分是静态区域部分。right和bottom(下和右)边框中交叉部分则是内容部分。
如上图《也就是说,在手机里。无论上面那张图怎么放大,四周的圆角都是不会被放大的!只有left(左)和top(上)边框内才会伸缩!
在 Android中以9.PNG格式的图片未背景,则能够自定义拉伸而不失真,比如系统的Button就是一个典型的例子。其实呢,无论是left和 top,还是right和bottom都是把图片分成9块 (边角四块是不能缩放的,其他的四块则是允许缩放的),所以叫做9.PNG。
关于draw9patch工具的使用在此不做阐述,需要的可以自己去百度一下。
Layout资源
有时候可能由于屏幕布局过于复杂,同一个布局文件很难适应所有的屏幕分辨率。可以像drawable资源一样,在工程的res文件夹下建立多个相应的layout文件夹,为相应分辨率的屏幕编写相应的layout文件。
文件夹的命名规范是这样的:layout-分辨率
例如:layout-320x240 , layout-480x320等等。
系统就会根据运行环境的分辨率优先加载相应的文件夹下的layout布局文件。