1. 界面适配
1、基本概念
屏幕大小(screen size) – 屏幕的实际大小,用屏幕对角线长度来衡量(比如3.4寸,3.8寸)。android把屏幕分为以下4种:small,normal,large,extra large。
怎么判断?
屏幕密度(Screen Density) - 一块实际的屏幕区域有多少个像素,一般用dpi衡量(每英寸有多少个点)。相比起medium、high屏幕密度的设备,在一块确定大小的屏幕区域l密度为low的屏幕拥有的像素更少。android把屏幕密度分为4种:low,medium,high,extra high。
如何判断是ldpi,mdpi,hdpi?
方向(orientation) - 屏幕方向分为landscape(横屏)和portrait(竖屏)。
分辨率(Resolution) - 屏幕上的总实际像素数。对屏幕进行适配时,一般不关注它的分辨率,只关注它的屏幕大小和密度。
与密度无关的像素(Density-independent pixel,dp或dip) - 为了保证你的UI适合不同的屏幕密度,建议你采用dp来定义程序UI。
它的计算方法为:px = dp * (dpi / 160)
sp(scale-independent pixel)
如何分辨一个屏幕是ldpi、mdpi、hdpi的方法,见下图
计算屏幕密度
2、怎样适配多种屏幕
a.在manifest里定义你的程序支持的屏幕类型,相应代码如下:
<supports-screens android:resizeable=["true"| "false"]
android:smallScreens=["true" | "false"] //是否支持小屏
android:normalScreens=["true" | "false"] //是否支持中屏
android:largeScreens=["true" | "false"] //是否支持大屏
android:xlargeScreens=["true" | "false"] //是否支持超大屏
android:anyDensity=["true" | "false"] //是否支持多种不同密度的屏幕
android:requiresSmallestWidthDp=”integer”
android:compatibleWidthLimitDp=”integer”
android:largestWidthLimitDp=”integer”/>
b.对不同大小的屏幕提供不同的layout。
比如,如果需要对大小为large的屏幕提供支持,需要在res目录下新建一个文件夹layout-large/并提供layout。当然,也可以在res目录下建立layout-port和layout-land两个目录,里面分别放置竖屏和横屏两种布局文件,以适应对横屏竖屏自动切换。
c.对不同密度的屏幕提供不同的图片。
应尽量使用点9格式的图片,如需对密度为low的屏幕提供合适的图片,需新建文件夹drawable-ldpi/,并放入合适大小的图片。相应的,medium对应drawable-mdpi /,high对应drawable-hdpi/,extra high对应drawable-xhdpi/。
图片大小的确定:low:medium:high:extra high比例为3:4:6:8。举例来说,对于中等密度(medium)的屏幕你的图片像素大小为48×48,那么低密度(low)屏幕的图片大小应为36×36,高(high)的为72×72,extra high为96×96。
不同密度的屏幕对应的图片比例
3、多屏幕适配的4条黄金原则
a.在layout文件中设置控件尺寸时应采用wrap_content,fill_parent和dp。
具体来说,设置view的属性android:layout_width和android:layout_height的值时,wrap_content,fill_parent或dp比pix更好。相应地,为了使文字大小更好的适应屏幕应该使用sp来定义文字大小。
b.在程序的代码中不要出现具体的像素值。
为了使代码简单,android内部使用pix为单位表示控件的尺寸,但这是基于当前屏幕基础上的。为了适应多种屏幕,android建议开发者不要使用具体的像素来表示控件尺寸。
c.不要使用AbsoluteLayout(android1.5已废弃) 。相应地,应使用RelativeLayout。
d.对不同的屏幕提供合适大小的图片。见上面第2部分。
4、需要注意的地方
以上设置适用于android3.2以下的版本。(本人目前开发是在android2.2上,这部分以后再补充)
5、怎样测试你的程序是否支持多屏幕适配
一般使用AVD Manager创建多个不同大小的模拟器,如下图
(1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
(2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480)
(3)drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320)
ldpi:240x320
mdpi:320x480
hdpi:480x800、480x854
xhdpi:至少960*720
xxhdpi:1280×720
android 自适应 多屏幕支持
1、屏幕相关概念
1.1分辨率
是指屏幕上有横竖各有多少个像素
1.2屏幕尺寸
指的是手机实际的物理尺寸,比如常用的2.8英寸,3.2英寸,3.5英寸,3.7英寸
1英寸=25.4毫米
android将屏幕大小分为四个级别(small,normal,large,and extra large)
像素密度达到326像素/英寸(ppi),称之为“视网膜屏幕”。
2. 基本概念
屏幕大小(screen size)
屏幕的实际大小,用屏幕对角线长度来衡量(比如3.4寸,3.8寸)。android把屏幕分为以下4种:small,normal,large,extra large。
怎么判断?
屏幕密度(Screen Density) -
一块实际的屏幕区域有多少个像素,一般用dpi衡量(每英寸有多少个点)。相比起medium、high屏幕密度的设备,在一块确定大小的屏幕区域l密度为low的屏幕拥有的像素更少。android把屏幕密度分为4种:low,medium,high,extra high。
如何分辨一个屏幕是ldpi、mdpi、hdpi的方法,见下图
计算屏幕密度
方向(orientation) -
屏幕方向分为landscape(横屏)和portrait(竖屏)。
分辨率(Resolution) -
屏幕上的总实际像素数。对屏幕进行适配时,一般不关注它的分辨率,只关注它的屏幕大小和密度。
与密度无关的像素(Density-independent pixel,dp或dip) - 为了保证你的UI适合不同的屏幕密度,建议你采用dp来定义程序UI。
它的计算方法为:px = dp * (dpi / 160)
sp(scale-independent pixel)
2、怎样适配多种屏幕
在manifest里定义你的程序支持的屏幕类型,相应代码如下:
<supports-screens android:resizeable=["true"| "false"] |
b.对不同大小的屏幕提供不同的layout。
比如,如果需要对大小为large的屏幕提供支持,需要在res目录下新建一个文件夹layout-large/并提供layout。当然,也可以在res目录下建立layout-port和layout-land两个目录,里面分别放置竖屏和横屏两种布局文件,以适应对横屏竖屏自动切换。
res/layout/my_layout.xml // 用于normal 屏幕大小的布局 ("默认")
|
c.对不同密度的屏幕提供不同的图片。
应尽量使用点9格式的图片,如需对密度为low的屏幕提供合适的图片,需新建文件夹drawable-ldpi/,并放入合适大小的图片。相应的,medium对应drawable-mdpi /,high对应drawable-hdpi/,extra high对应drawable-xhdpi/。
图片大小的确定:low:medium:high:extra high比例为3:4:6:8。举例来说,对于中等密度(medium)的屏幕你的图片像素大小为48×48,那么低密度(low)屏幕的图片大小应为36×36,高(high)的为72×72,extra high为96×96。
不同密度的屏幕对应的图片比例
Density 160 1
2.1. 多屏幕适配建议
a.在layout文件中设置控件尺寸时应采用wrap_content,fill_parent和dp。
具体来说,设置view的属性android:layout_width和android:layout_height的值时,wrap_content,fill_parent或dp比pix更好。相应地,为了使文字大小更好的适应屏幕应该使用sp来定义文字大小。
b.在程序的代码中不要出现具体的像素值。
为了使代码简单,android内部使用pix为单位表示控件的尺寸,但这是基于当前屏幕基础上的。为了适应多种屏幕,android建议开发者不要使用具体的像素来表示控件尺寸。
c.不要使用AbsoluteLayout(android1.5已废弃) 。相应地,应使用RelativeLayout。
d.对不同的屏幕提供合适大小的图片。见上面第2部分。
4、需要注意的地方
以上设置适用于android3.2以下的版本。(本人目前开发是在android2.2上,这部分以后再补充)
5、怎样测试你的程序是否支持多屏幕适配
一般使用AVD Manager创建多个不同大小的模拟器
2.2. 独立密度dp px
维持独立密度是很重要的,因为没有它,一个UI元素(比如一个按钮)会出现在一个物理屏幕很大,但密度很少的显示效果(看起来就是像是被强行放大的,失真很严重)。这样相对位置的改变会出问题
图1是你的App没有支持不同密度产生的效果
图2是具有良好的支持程序为例产生的效果
android 系统帮助你的App实现独立密度的方法有两种:
系统缩放dp单位来适用当前屏幕密度The system scales dp units as appropriate for the current screen density
系统基于当前屏幕密度缩放drawable资源到适用的大小
图 1是用像素单位来定义的大小。 你发现他们的布局完全变了,有的大有的小。这是因为他们的实际屏幕大小可能是一样的,高密度屏幕每英寸的像素更多(所以你会发现像素一样,但高密度的设备显示出来的效果却很小)。图2使用的是dp单位,基于mdpi密度的设备它不会变化,ldpi它会自动缩小,hdpi它会自动放大。
2.3. 特征表
屏幕特征 | 后缀 | 描述 |
大小 | small | 资源用于small大小的屏幕. |
normal | 资源用于normal 大小的屏幕。(这是默认的基准大小) | |
large | 资源用于large 大小的屏幕 | |
xlarge | 资源用于extra large 大小的屏幕 | |
密度 | ldpi | 资源用于 low-density (ldpi) 密度的屏幕 (~120dpi). |
mdpi | 资源用于medium-density (mdpi) 密度的屏幕 (~160dpi). (这是默认的基准密度.) | |
hdpi | 资源用于high-density (hdpi) 密度的屏幕 (~240dpi). | |
xhdpi | 资源用于extra high-density (xhdpi) 密度的屏幕 (~320dpi). | |
nodpi | 资源用于所有密度. 系统不会根据当前屏幕密度去缩放资源 | |
tvdpi | 资源用于mdpi 和hdpi两者之间的某的密度;大约是213dpi。 这个很少用到。它主要用于电视,大多数App不需要用到它。如果你需要tvdpi资源,它的大小大概是1.33*mdpi(160)例如,一个在mdpi下100px*100px的图片,那么在 tvdpi中它会变成133px*133px。 | |
方向 | land | 资源用于横屏 |
port | 资源用于竖屏 | |
长宽比 | long | 资源用于长宽比相差很远的配置(相对于4寸(normal)屏幕左右基准屏幕) |
notlong | 资源用于长宽比差不多的配置(相对论,同上) |
以下是android3.2进入的新后缀(注意是基于屏幕大小的而不是密度)
2.4. 使用新的大小后缀(非密度)
屏幕 配置 | 后缀值 | 描述 |
最小宽度 | sw<N>dp | 用这个后缀可以确保不管当前屏幕是否横竖屏。你的App有一个至少<N>dp的可用宽度 例如, 如果你的layout一直需求最小屏幕的一边为600dp,那么你能使用这个后缀创建layout资源(res/layout-sw600dp/)。对于用户来讲,不管600dp是宽还是高,仅当屏幕可用的最小尺寸至少是600dp时,系统会使用这些资源(就是说你的设备不用以什么角度看,长和宽的某一边的最小值大于或等于600dp时,系统就会使用。)。当屏幕水平方向改变时,设备的最小宽度不会改变 设备的最小宽度要考虑屏幕的装饰和系统UI。例如,如果设备有一些持续不变的沿着你最小宽度的轴方向的UI元素(动作条等),那么系统会宣布最小宽度比实际屏幕宽度要小,因为那些UI元素对于你的UI来说是不可用的 因为宽度是经常影响布局的一个重要因素,所以使用最小宽度来控制一般的屏幕大小(针对平板)还是有用的。 可用宽度也是决定是否使用单屏幕布局(手机)和多屏幕布局(平板)关键因素,因此你很可能关心每一个设备上的最小方面。 |
屏幕可用宽度 | w<N>dp | 用dp单位指定一个最小化的在可用宽度下可以使用的资源。系统会根据宽度改变(横竖屏切换时)来匹配这个值,并反映到当前实际可用的宽度上 当你决定是否使用多屏幕布局时它很有用,因为即使在平板设备上,你也经常不想要多屏幕布局会根据横竖屏来变化。因此你可以用这个来指定最小化的宽度需求,它可以用来代替方向后缀(land,port)和大小后缀(small,normal,large,xlarge)使之整合到一起。 |
屏幕可用高度 | h<N>dp | 用dp单位指定一个最小化的屏幕高度。和"屏幕可用宽度"类似 |
可能对于平板布局你需要720dp的宽度,可能600dp就足够了,或者480,或者这两个之间。使用表格2的后缀,你可以在布局改变时精确的控制大小。以后我们会根据实际开发来讲述的
配置例子
以下是一些屏幕数据:
320dp: 一种手机屏幕(240x320 ldpi, 320x480 mdpi, 480x800 hdpi, 等).
480dp: 一种平板 (480x800 mdpi).
600dp: 7寸平板(600x1024 mdpi).
720dp: 10寸平板(720x1280 mdpi, 800x1280 mdpi, 等).
我们使用表格2中的后缀来为我们的App定义不同的切换风格(包括手机和平板),例如, 如果我们的平板布局600dp是最小可用宽度,我们能提供两套布局方式:
res/layout/main_activity.xml # 手机
res/layout-sw600dp/main_activity.xml # 平板
这种情况下,屏幕可用的最小宽度为600dp,这是伪了支持平板布局被应用。
或者你可能想要区分7寸和10寸平板,你可以这么做:
res/layout/main_activity.xml # 手机(比600dp更小的可用宽度)
res/layout-sw600dp/main_activity.xml # 7寸平板 (600dp的宽度或者更大)
res/layout-sw720dp/main_activity.xml # 10寸平板(720dp的宽度或者更大)
注意上面的两套例子的使用使用 sw(最小宽度)后缀,它指定屏幕的两边中的最小一边,不管屏幕的水平方向。它忽视横竖屏。
然而某些情况下我们需要精确布局。例如如果你有一个 2个面板合并在一起的显示效果。是否屏幕提供至少600dp的宽度,是否横竖屏你都要使用它。就应该这:
res/layout/main_activity.xml # 手机(小于600dp的可用宽度)
res/layout-w600dp/main_activity.xml #多面板 (任意一个面板都是600dp或者更高的宽度)
注意上面这里用的是w<n>dp。实际设备可能需要两套布局,它依赖于屏幕的水平方向(一边至少是600dp的宽度,另一边小于600dp,你会发现不管横竖屏都满足这个条件。所以你需要准备两套关于横竖屏的布局)
3. 附件
3.1. LinearLayout:
android:id 为控件指定相应的ID android:text 指定控件当中显示的文字,需要注意的是,这里尽量使用strings.xml 文件当中的字符 android:grivity 指定控件的基本位置,比如说居中,居右等位置 android:textSize 指定控件当中字体的大小 android:background 指定该控件所使用的背景色,RGB命名法 android:width 指定控件的宽度android:height 指定控件的高度android:padding* 指定控件的内边距,也就是说控件当中的内容 android:sigleLine 如果设置为真的话,则将控件的内容在同一行当中进行显示
|
3.2. RelativeLayout
android:layout_above 将该控件的底部至于给定ID的控件之上 android:layout_below 将该控件的顶部至于给定ID的控件之下 android:layout_toLeftOf 将该控件的右边缘和给定 ID的控件的左边缘对齐 android:layout_toRightOf 将该控件的左边缘和给定ID 的控件的右边缘对齐 android:layout_alignBaseline 该控件的baseline和给定ID的控件的baseline对齐 android:layout_alignBottom 将该控件的底部边缘与给定ID控件的底部边缘 android:layout_alignLeft 将该控件的左边缘与给定ID控件的左边缘对齐 android:layout_alignRight 将该控件的右边缘与给定ID控件的右边缘对齐 android:layout_alignTop 将给定控件的顶部边缘与给定 ID控件的顶部对齐 android:alignParentBottom 如果该值为true,则将该控件的底部和父控件的底部对齐 android:layout_alignParentLeft 如果该值为true,则将该控件的左边与父控件的左边对齐 android:layout_alignParentRight 如果该值为 true,则将该控件的右边与父控件的右边对齐 android:layout_alignParentTop 如果该值为true,则将空间的顶部与父控件的顶齐 android:layout_centerHorizontal 如果值为真,该控件将被至于水平方向的中央 android:layout_centerInParent 如果值为真,该控件将被至于父控件水平方向和垂直方向的中央 android:layout_centerVertical 如果值为真,该控件将被至于垂直方向的中央
|