android分辨率问题

来源:互联网 发布:appche 转发 node 编辑:程序博客网 时间:2024/05/29 06:26

一、Android手机目前常见的分辨率
4:3
VGA 640*480 (Video Graphics Array)
QVGA 320*240 (Quarter VGA)
HVGA 480*320 (Half-size VGA)
SVGA 800*600 (Super VGA)
5:3
WVGA 800*480 (Wide VGA)
16:9
FWVGA 854*480 (Full Wide VGA)
HD 1920*1080 High Definition
QHD 960*540
720p 1280*720 标清
1080p 1920*1080 高清

分辨率对应DPI
HVGA mdpi 160dpi
WVGA hdpi 240dpi
FWVGA hdpi 240dpi
QHD hdpi 240dpi
720P xhdpi 320dpi
1080P xxhdpi 480dpi

二、遇到一个问题,我的地图浮标图片在WVGA手机上正好,在QVGA上就显的太大,所以我要根据屏幕的不同调整浮标的大小使其在QVGA大小合适。有的同事提出了依据分辨率来区分不同的屏幕,但是单WVGA就支持好几种不同的分辨率,QVGA又支持好几种。。。而且更神奇的时候,有时候,通过代码获取屏幕分辨率竟然得到了 320 x 427 ,Android文档是不支持这种分辨率的,所以依据分辨率来区分不同的屏幕是行不通的。

   还好通过仔细研读文档,“各种VGA的density是不同的,(hdpi: 240 , ldpi: 120 , mdpi: 160 , xhdpi: 320)”,所以只要求出不同屏幕的density,就可以知道该手机属于的屏幕类型。

首先是几个基本概念:

1.屏幕尺寸Screen size

即显示屏幕的实际大小,按照屏幕的对角线进行测量

为简单起见,Android把所有的屏幕大小分为四种尺寸:小,普通,大,超大(分别对应:small, normal, large, and extra large).

应用程序可以为这四种尺寸分别提供不同的自定义屏幕布局-平台将根据屏幕实际尺寸选择对应布局进行渲染,这种选择对于程序侧是透明的。

2.屏幕长宽比Aspect ratio

长宽比是屏幕的物理宽度与物理高度的比例关系。应用程序可以通过使用限定的资源来为指定的长宽比提供屏幕布局资源。

3.屏幕分辨率Resolution

在屏幕上显示的物理像素总和。需要注意的是:尽管分辨率通常用宽x高表示,但分辨率并不意味着具体的屏幕长宽比。

在Andorid系统中,应用程序不直接使用分辨率。

4.密度Density

根据像素分辨率,在屏幕指定物理宽高范围内能显示的像素数量。
在同样的宽高区域,低密度的显示屏能显示的像素较少,而高密度的显示屏则能显示更多的像素。

屏幕密度非常重要,因为其它条件不变的情况下,一共宽高固定的UI组件(比如一个按钮)在在低密度的显示屏上显得很大, 而在高密度显示屏上看起来就很小。

为简单起见,Android把所有的屏幕分辨率也分为四种尺寸:小,普通,大,超大(分别对应:small, normal, large, and extra large).

应用程序可以为这四种尺寸分别提供不同的资源-平台将透明的对资源进行缩放以适配指定的屏幕分辨率。

密度无关的像素( DIP )
指一个抽象意义上的像素,程序用它来定义界面元素。它作为一个与实际密度无关的单位,帮助程序员构建一个布局方案(界面元素的宽度,高度,位置)。
一个与密度无关的像素,在逻辑尺寸上,与一个位于像素密度为 160DPI的屏幕上的像素是一致的,这也是Android平台所假定的默认显示设备。在运行的时候,平台会以目标屏幕的密度作为基准,“透明地”处理所 有需要的DIP缩放操作。要把密度无关像素转换为屏幕像素,可以用这样一个简单的公式: pixels = dips * (density / 160)。举个例子,在 DPI为 240的屏幕上, 1个 DIP等于 1.5个物理像素。我们强烈推荐你用 DIP来定义你程序的界面布局,因为这样可以保证你的 UI在各种分辨率的屏幕上都可以正常显示

那么如何获取屏幕的密度呢?

方法一:
在一个Activity的onCreate方法中,写入如下代码:

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/ 320)
但是,需要注意的是,在一个低密度的小屏手机上,仅靠上面的代码是不能获取正确的尺寸的。比如说,一部240x320像素的低密度手机,如果运行上述代码,获取到的屏幕尺寸是320x427。因此,研究之后发现,若没有设定多分辨率支持的话,Android系统会将240x320的低密度(120)尺寸转换为中等密度(160)对应的尺寸,这样的话就大大影响了程序的编码。所以,需要在工程的AndroidManifest.xml文件中,加入supports-screens节点,具体的内容如下:    <supports-screens        android:smallScreens="true"        android:normalScreens="true"        android:largeScreens="true"        android:resizeable="true"        android:anyDensity="true"/>这样的话,当前的Android程序就支持了多种分辨率,那么就可以得到正确的物理尺寸了。

方法2:

DisplayMetrics dm = new DisplayMetrics();  dm = getResources().getDisplayMetrics();  float density  = dm.density;        // 屏幕密度(像素比例:0.75/1.0/1.5/2.0)  int densityDPI = dm.densityDpi;     // 屏幕密度(每寸像素:120/160/240/320)  float xdpi = dm.xdpi;             float ydpi = dm.ydpi;  screenWidth  = dm.widthPixels;      // 屏幕宽(像素,如:480px)  screenHeight = dm.heightPixels;     // 屏幕高(像素,如:800px)  

重中之重:
density值表示每英寸有多少个显示点,与分辨率是两个不同的概念:
Android主要有以下几种屏:

QVGA和WQVGA屏density=120;

HVGA屏density=160;

WVGA屏density=240;

当density=120时 屏幕实际分辨率为240px*400px (两个点对应一个分辨率)
状态栏和标题栏高各19px或者25dip
横屏是屏幕宽度400px 或者800dip,工作区域高度211px或者480dip
竖屏时屏幕宽度240px或者480dip,工作区域高度381px或者775dip

density=160时 屏幕实际分辨率为320px*533px (3个点对应两个分辨率)
状态栏和标题栏高个25px或者25dip
横屏是屏幕宽度533px 或者800dip,工作区域高度295px或者480dip
竖屏时屏幕宽度320px或者480dip,工作区域高度508px或者775dip

density=240时 屏幕实际分辨率为480px*800px (一个点对于一个分辨率)
状态栏和标题栏高个38px或者25dip
横屏是屏幕宽度800px 或者800dip,工作区域高度442px或者480dip
竖屏时屏幕宽度480px或者480dip,工作区域高度762px或者775dip

apk的资源包中,
当屏幕density=480时,使用xxhdpi的资源包
当屏幕density=320时,使用xhdpi标签的资源
当屏幕density=240时,使用hdpi标签的资源
当屏幕density=160时,使用mdpi标签的资源
当屏幕density=120时,使用ldpi标签的资源。
不加任何标签的资源是各种分辨率情况下共用的。
建议:布局时尽量使用单位dip,少使用px。

三、屏幕适配的注意事项
1 基本设置
1.1.1 AndroidManifest.xml设置
在中Menifest中添加子元素
android:anyDensity=”true”时,应用程序安装在不同密度的终端上时,程序会分别加载相应的xxhdpi、xhdpi、hdpi、mdpi、ldpi文件夹中的资源。相反,如果设为false,即使在文件夹下拥有相同资源,应用不会自动地去相应文件夹下寻找资源,规则如下:

1.1.2 横屏竖屏目录区分
1) drawable
a) drawable-hdpi该图片即适用于横屏,也适用于竖屏;
b) drawable-land-hdpi,当屏幕为横屏,且为高密度时,加载此文件夹的资源;
c) drawable-port-hdpi,当屏幕为竖屏,且为高密度时,加载此文件夹中的资源。其他同理。
2) layout
在res目录下建立layout-port和layout-land两个目录,里面分别放置竖屏和横屏两种布局文件,以适应对横屏竖屏自动切换。
2.2 多屏幕适配的4条黄金原则
1) 在layout文件中设置控件尺寸时应采用fill_parent、wrap_content、match_parent和dp;
具体来说,设置view的属性android:layout_width和android:layout_height的值时,wrap_content,match_parent或dp比px更好,文字大小应该使用sp来定义。
2) 在程序的代码中不要出现具体的像素值,在dimens.xml中定义;
为了使代码简单,android内部使用pix为单位表示控件的尺寸,但这是基于当前屏幕基础上的。为了适应多种屏幕,android建议开发者不要使用具体的像素来表示控件尺寸。
3) 不使用AbsoluteLayout(android1.5已废弃) ,可以使用RelativeLayout替代;
4) 对不同的屏幕提供合适大小的图片。
不同大小屏幕用不同大小的图片,low:medium:high:extra-high图片大小的比例为3:4:6:8;举例来说,对于中等密度(medium)的屏幕你的图片像素大小为48×48,那么低密度(low)屏幕的图片大小应为36×36,高(high)的为72×72,extra-high为96×96。
2.3 使用9-patch PNG图片
使用图片资源时,如果出现拉伸,因为图片处理的原因,会变形,导致界面走形。9-patch PNG图片也是一种标准的PGN图片,在原生PNG图片四周空出一个像素间隔,用来标识PNG图片中哪些部分可以拉伸、哪些不可以拉伸、背景上的边框位置等。
“上、左”定义可拉伸区域
“右、下”定义显示区域,如果用到完整填充的背景图,建议不要通过android:padding来设置边距,而是通过9-patch方式来定义。
Android SDK中提供了编辑9-Patch图片的工具,在tools目录下draw9patch.bat,能够立刻看到编辑后的拉伸效果,也可以直接用其他图片编辑工具编辑,但是看不到效果。
2.4 不同的layout
Android手机屏幕大小不一,有480x320, 640x360, 800x480……
怎样才能让Application自动适应不同的屏幕呢?
其实很简单,只需要在res目录下创建不同的layout文件夹,比如:layout-640x360、layout-800x480……所有的layout文件在编译之后都会写入R.java里,而系统会根据屏幕的大小自己选择合适的layout进行使用。

0 0
原创粉丝点击