Android适配 获取手机屏幕的分辨率

如何将一个应用程序适配在不同的手机上,虽然这不算是一个技术问题,但是对于刚刚做屏幕的开发人员来说,还真不是一件多么简单的事情。

 

首先:你需要在AndroidManifest.xml文件的<manifest>元素如下添加子元素

<supports-screensandroid:largeScreens="true"

      android:normalScreens="true"android:anyDensity="true"

      android:smallScreens="true"></supports-screens>

 

    名如其意,以上是为我们的屏幕设置多分辨率支持(更准确的说是适配大、中、小三种密度)。android:anyDensity="true"这一句对整个的屏幕都起着十分重要的作用,值为true,我们的应用程序当安装在不同密度的手机上时,程序会分别加载hdpi,mdpi,ldpi文件夹中的资源。

 相反,如果值设置为false,即使我们在hdpi,mdpi,ldpi文件夹下拥有同一种资源,那么应用也不会自动地去相应文件夹下寻找资源,这种情况都是出现在高密度,以及低密度的手机上,比如说一部240×320像素的手机,如果设置android:anyDensity="false"Android系统会将240 x 320(低密度)转换为320×480(中密度),这样的话,应用就会在小密度手机上加载mdpi文件中的资源。

 

2.细心的人会发现自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文件夹中的资源

 

3. 注意上图各种文件夹的不同表示。

drawable-hdpi 该图片即适用于横屏,也适用于竖屏

drawable-land-hdpi,当屏幕为横屏,且为高密度时,加载此文件夹中的资源

drawable-port-hdpi,当屏幕为竖屏,且为高密度时,加载此文件夹中的资源

 

3. 有时候会根据需要在代码中动态地设置某个值,比如地图,地图的pin和地图的地址提示框的相对偏移量在不同密度的手机上是不同的。这时候可以通过以下方法求出屏幕密度:

 

DisplayMetrics metric = newDisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);

int densityDpi =metric.densityDpi;  //屏幕密度DPI120 / 160 / 240

 

然后可以在代码中为这几种密度分别设置便宜量

 

但是这种方法最好不要使用,最好的方式是在xml文件中不同密度的手机进行分别设置。

这里地图的偏移量可以在values-hpdi,values-mdpi,values-ldpi三种文件夹中的dimens.xml文件进行设置

值得一提的是:

   <dimenname="bitmap_common_topoffset">40dp</dimen>

   <dimenname="bitmap_common_bottomoffset">-14dp</dimen>

这里的负数是完全起作用的,系统会认为它是一个负值


4.各大手机厂商对于Android操作系统都有或多或少的改动,当然这些改动会对我们应用程序产生某些影响

  比如:

  (1)系统源代码中连接music服务的aidl文件所在包名:com.android.music 

  (2)LG则可能将该aidl文件修改所在的包(例如修改为com.android.music.player),并且修改其中的文件内容(增加一个方法,或者减少几个方法,或者修改方法名称)那么我们的应用要想在LG的手机上发布,那么我们就必须改变所要连接的aidl文件,必须跟LG厂商修改的完全一致。

  

5. 国际化问题.

  有时候在xml中设置了相应的语言,但是为什么当我们更改语言之后,UI显示仍然不起作用?

  不要怀疑是系统出了问题,这与我们在代码中引用values/string.xml中字符串的方式有关。

   错误的方式:

   1. 声明全局变量private static String tempStr;

   2.在onCreate方法中对该变量赋值 tempStr =context.getString(R.string.test);

   3.在更新UI的方法(非onCreate方法)中引用该变量。textView.setText(tempStr);

   原因是由于,当修改本地语言时,onCreate不会再被执行一遍. 变量tempStr依然会使用页面刚启动时加载的默认英语。


   正确的方式:

  直接进行第三步:textView.setText(context.getString(R.string.test));




关于手机分辨率相关术语和概念

屏幕尺寸:实际的物理尺寸,屏幕的对角线测量。为了方便,android把所有的屏幕尺寸分为了4个广义的大小:小,正常,大,特大。

屏幕密度:屏幕的物理面积内像素的数量,通常称为DPI(每英寸点数)。为了方便,android把所有的实际屏幕密度分为:低,中,高,特高。

方向:从用户的角度来看,就是屏幕的方向,就是横向或者纵向的意义。

分辨率:屏幕上面的物理像素总数。(官方说法,应用程序应该只关注屏幕大小和密度)

密度无关像素: 一个虚拟像素单元(官方说法,你应该使用密度无关像素定义UI的布局,来表达布局尺寸或位置,系统默认假设“中等”的密度屏幕为基准,其屏幕密度相当于一个160dpi的屏幕。在运行时,系统根据实际中的屏幕密度对DP单位进行缩放。DP单位转换为屏幕像素可用PX = DP *(DPI / 160)这个方法。那么在一个160dpi屏幕上,1DP==1PX。在一个240 dpi屏幕上,1 DP==1.5PX。那么在定义布局时,应该使用DP单位,以确保不同密度的屏幕上合理的显示用户界面)

关于支持屏幕的范围

官方定义4种广义尺寸:小,正常, 大,更大。四种密度:低,中型, 高,特高。广义尺寸和密度都可以跨越一系列的尺寸和密度(官方截图上传不了权限不够一周<img title=”[android 屏幕适配]关于android分辨率兼容问题(一)[转]” src=”http://static.blog.csdn.net/xheditor/xheditor_emot/default/wronged.gif” alt=”委屈” />)

关于密度的独立性

官方说法保证密度的独立性是非常重要的,如果没有它,你应用程序中的系统控件可能会在物理尺寸相同,密度不同的屏幕上面显示异常。

Android系统帮助密度独立有两种方式:

1.使用DP单位。

2.位图资源缩放,可以导致像素模糊的位图,可以根据当前屏幕密度,提供不同分辨率的位图。官方提示,如果提供一套图至少提供更高分辨率高密度的位图而不是提供哪些中等密度设计的位图。

关于如何支持多个屏幕

官方说法确保系统在适配多个屏幕做了很多工作,但是为了更妥善处理不同的屏幕配置,我们也需要做些工作:

1.在程序中显示声明你的应用程序支持屏幕尺寸的清单。

<span style=”font-family:KaiTi_GB2312;font-size:16px;”>
android:resizeable=[“true”|”false”]
android:smallScreens=[“true”|”false”]
android:normalScreens=[“true”|”false”]
android:largeScreens=[“true”|”false”]
android:xlargeScreens=[“true”|”false”]
android:anyDensity=[“true”|”false”]/></span>

2.根据不同屏幕尺寸,提供不同布局

默认情况下面,android会自动调整应用程序的布局,但是大多数情况下面,根据广义尺寸,小,正常,大,更大去增加不同的布局资源。比如,如果需要对大小为large的屏幕提供支持,需要在res目录下新建一个文件夹layout-large/并提供layout。当然,也可以在res目录下建立layout-port和layout-land两个目录,里面分别放置竖屏和横屏两种布局文件,以适应对横屏竖屏自动切换。

3.提供不同的屏幕密度和不同的位图drawables

默认情况下面系统会自动调整和缩放位图,但是难免拉伸位图,为了保证你的位图是最好看的,根据广义密度,低,中型, 高,特高去添加不同的位图资源。比如,如需对密度为low的屏幕提供合适的图片,需新建文件夹drawable-ldpi/。应尽量使用点9格式的图片,图片大小的确定:low:medium:high:extra high比例为3:4:6:8。举例来说,对于中等密度(medium)的屏幕你的图片像素大小为48×48,那么低密度(low)屏幕的图片大小应为36×36,高(high)的为72×72,extra high为96×96。

关于系统怎么动态的寻找替代资源?

1.系统根据当前的屏幕大小和密度,然后动态的采用程序中提供特定的资源。

2.如果没有匹配的资源,系统会使用默认的资源进行缩放从而符合当前屏幕的资源,“默认”的资源是那些没有标签配置限定符。

(这块只是简单的说法,详细关于介绍寻找替代资源下章在说吧)

关于系统的资源配置的目录(我只列出一些大概,默认项目会有一些资源配置目录)

Android系统支持多配置资源文件,我们可以追加新的资源目录到你的Android项目中。命名规范: 资源名字-限制符

layout

默认中等屏幕

layout-small

小屏幕

layout-large

大屏幕

layout-xlarge

特大屏幕

layout-land

横屏

layout-port

竖屏

drawable

默认中等密度

drawable-hdpi

高密度 ~240dpi

drawable-mdpi

中等密度 160dpi

drawable-xhdpi

更高密度 ~320dpi

drawable-nodpi

所有密度资源,无论什么密度屏幕都会适配。

drawable-tvdpi

介于mdpi~hdpi 约213dpi 主要应用在电视。

注:如果没有指定横屏或竖屏,则上面的布局和位图都适配横竖屏。如果要指定横屏,例如:drawable-land-hdpi竖屏drawable-port-hdpi,还有关键是drawable-xlarge和layout-xlarge,对api level都要求在9之上,等于说,你用android2.2系统的平板或者手机根本不匹配layout-xlarge。因为api level是8。drawable-tvadpi这个api等级需要13以上。

其实上面的layout-large这个目录其实是个范围。当系统根据当前屏幕的大小和密度,决定程序应该匹配那个目录。你也可以单独定制某些不符合谷歌标准的山寨版layout-l024x600(中间的符合是英文下的x字母),其中1024和600的单位是dp。你可以根据你设备的分辨率和密度,来判断你的设备需要定义那个文件。

但是,官方推荐使用尺寸来表示资源layout-large,不推荐使用分辨率layout-1024*600。

建议大家多看文档,官方说明:

xlarge screens are at least 960dp x 720dp

large screens are at least 640dp x 480dp

normal screens are at least 470dp x 320dp

small screens are at least 426dp x 320dp

上面是定义广义大小布局资源适配的一个范围,大家可以根据自己的设备知道系统会匹配那个文件的布局。

如果手上有个山寨华为的卖的比较火的mediapad,大家知道分辨率1280*800 密度尺寸7寸

通过勾股定了和分辨率可以得出其密度为215.69。然后根据dp=px/(dpi/160),可以得出个范围593.471。所以这个设备系统会匹配layout-large这个资源布局文件。



andorid界面单位开发是应该是dip

自适应,包括元素大小自适应,和位置自适应。

元素大小:

图片默认会自适应的。

dip会自适应。

自适应问题。一个公式 px=dip*(density/160);(density/160)在android系统中对应 DisplayMetrics.density在一固定的手机上它是一个常数,0.75,1,1.5。等。有了这个常数用dip做单位在不同手机上就有不同的px了。这就是缩放原理。

drawable-hdpi、drawable-mdpi、drawable-ldpi中的图片是自动选择的。但是如果对应的文件夹下没有所需的图片它会在其他两个文件夹下寻找,找到了按density缩放。

元素坐标:

图片坐标,和触屏事件坐标。 都用相对坐标 

 

 

自适应原则:图片缩放自适应,位置用相对位置(单位也用dip)。

所有的机型宽都是相等的dip数,高不一定是相等的dip数。

 

240x320 density=120 320dipx426.6dip

320x480 density=160 320dipx480dip

480x800 density=240 320dipx533.3dip

480x854 density=240 320dipx569.33dip

 

        我感觉,做手机的屏幕自适应比做web的浏览器兼容更麻烦..以下是搜到的资料,原来android还有这些不为人知的东西: 
一:不同的layout 
Android手机屏幕大小不一,有480x320, 640x360, 800x480.怎样才能让App自动适应不同的屏幕呢?  
   其实很简单,只需要在res目录下创建不同的layout文件夹,比如layout-640x360,layout-800x480,所有的layout文件在编译之后都会写入R.java里,而系统会根据屏幕的大小自己选择合适的layout进行使用。 
二:hdpi、mdpi、ldpi 
在之前的版本中,只有一个drawable,而2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三个,这三个主要是为了支持多分辨率。 
drawable- hdpi、drawable- mdpi、drawable-ldpi的区别: 
(1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854) 
(2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480) 
(3)drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320) 
系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。 
在开发程序时为了兼容不同平台不同屏幕,建议各自文件夹根据需求均存放不同版本图片。


1.术语和概念

术语

说明

备注

Screen size(屏幕尺寸)

指的是手机实际的物理尺寸,比如常用的2.8英寸,3.2英寸,3.5英寸,3.7英寸

摩托罗拉milestone手机是3.7英寸

Aspect Ratio(宽高比率)

指的是实际的物理尺寸宽高比率,分为long和nolong

Milestone是16:9,属于long

Resolution(分辨率)

和电脑的分辨率概念一样,指手机屏幕纵、横方向像素个数

Milestone是854*480

DPI(dot per inch)

每英寸像素数,如120dpi,160dpi等,假设QVGA(320*240)分辨率的屏幕物理尺寸是(2英寸*1.5英寸),dpi=160

可以反映屏幕的清晰度,用于缩放UI的

Density(密度)

屏幕里像素值浓度,resolution/Screen size可以反映出手机密度,

 

Density-independent pixel (dip)

指的是逻辑密度计算单位,dip和具体像素值的对应公式是dip/pixel=dpi值/160,也就是 px = dp * (dpi / 160)

 

 

2. DPI值计算

比如:计算WVGA(800*480)分辨率,3.7英寸的密度DPI,如图1所示

 

 

               图1 

Diagonal pixel表示对角线的像素值(=  ),DPI=933/3.7=252

 

3.手机屏幕的分类

 

3.1根据手机屏幕密度(DPI)或屏幕尺寸大小分为以下3类,如图2所示

 

 

                         

                          图2

 

3. 2手机屏幕分类和像素密度的对应关系如表1所示:

 

Low density (120), ldpi

Medium density (160), mdpi

High density (240), hdpi

Small screen

QVGA (240x320)

 

 

Normal screen

WQVGA400 (240x400)WQVGA432 (240x432)

HVGA (320x480)

WVGA800 (480x800)WVGA854 (480x854)

Large screen

 

WVGA800* (480x800)WVGA854* (480x854)

 

                                      表1

3.3手机尺寸分布情况( http://developer.android.com/resources/dashboard/screens.html )如图3所示,目前主要是以分辨率为800*480和854*480的手机用户居多


 

                                                        图3

   从以上的屏幕尺寸分布情况上看,其实手机只要考虑3-4.5寸之间密度为1和1.5的手机

4 UI设计

从开发角度讲,应用程序会根据3类Android手机屏幕提供3套UI布局文件,但是相应界面图标也需要提供3套,如表2所示

Icon Type

Standard Asset Sizes (in Pixels), for Generalized Screen Densities

 

Low density screen (ldpi)

Medium density screen (mdpi)

High density screen (hdpi)

Launcher

36 x 36 px

48 x 48 px

72 x 72 px

Menu

36 x 36 px

48 x 48 px

72 x 72 px

Status Bar

24 x 24 px

32 x 32 px

48 x 48 px

Tab

24 x 24 px

32 x 32 px

48 x 48 px

Dialog

24 x 24 px

32 x 32 px

48 x 48 px

List View

24 x 24 px

32 x 32 px

48 x 48 px

                                        表2

5 如何做到自适应屏幕大小呢?

1)界面布局方面 

   需要根据物理尺寸的大小准备5套布局,layout(放一些通用布局xml文件,比如界面中顶部和底部的布局,不会随着屏幕大小变化,类似windos窗口的title bar),layout-small(屏幕尺寸小于3英寸左右的布局),layout-normal(屏幕尺寸小于4.5英寸左右),layout-large(4英寸-7英寸之间),layout-xlarge(7-10英寸之间)

2)图片资源方面 

  需要根据dpi值准备5套图片资源,drawable,drawalbe-ldpi,drawable-mdpi,drawable-hdpi,drawable-xhdpi

Android有个自动匹配机制去选择对应的布局和图片资源

 

今天一个开发者问到我为什么游戏开发要删除项目下的hdpi、mdpi和ldpi文件夹;下面详细给大家解答一下:

         首先童鞋们如果看过我写的《 【Android游戏开发二十一】Android os设备谎言分辨率的解决方案! 》这一节的话都应该知道Android从1.6和更高,Google为了方便开发者对于各种分辨率机型的移植而增加了自动适配的功能;

        自动适配的原理很简单,只要你建立的项目是1.6或者更高都会看到项目下有drawable-hdpi、drawable-mdpi、drawable-ldpi 三个文件夹,这三个文件夹分别放置高清分辨率、中分辨率、低分辨率的资源文件;那么如果你的项目在高清分辨率上运行的话,系统会默认索引drawable-hdpi文件夹下的资源,其他雷同;

         那么既然系统会自动找匹配的文件夹,那么肯定会出现找不到的情况,比如当前你的应用在高清分辨率运行,假设代码中加载一张“himi.png”的图,那么系统首先会去drawable-hdpi文件夹下去找这张图,一旦找不到,系统会再到其他drawable下寻找,再假设你其实把这张“himi.png”放在了drawable-mdpi中,那么系统会默认把这张图片放大;反之一样,如果你在低分辨率中运行加载一张图片的话,一旦你将图片放入高清的drawable-dpi中,那么系统默认缩小这张图;

        总结来说:如果你的应用想适配高、中、低分辨率,那么你需要有3套图放入对应的文件夹中,这样系统会智能加载;如果你就想保留一个文件夹,不想让系统智能寻找缩放的话,有两种方式可以解决:

       1.删除drawable-hdpi、drawable-mdpi、drawable-ldpi三个文件夹,创建一个drawable文件夹即可;

       2.将资源文件放入assets中,因为assets中的资源系统永远不会为其生成id,所以不会智能缩放;

      -------------------下面介绍第二点,如何让你的游戏应用高清

      其实还是在《 【Android游戏开发二十一】Android os设备谎言分辨率的解决方案! 》中介绍过,1.6后android有了智能判断的缘故,你获取的屏幕宽高其实是不准确的,详情可以参考 【Android游戏开发二十一】Android os设备谎言分辨率的解决方案! 》;那么这里要补充一点就是:

      如果你在AndroidMainFest 中,定义  <uses-sdk android:minSdkVersion="4" /> 就OK了!你会发现你的图片很清楚,其实也是因为android自动缩放造成的,上面说了,一般获取的分辨率会不正常(比正确的偏小)那么一旦你加上这一句之后,你的分辨率就正常了,所以就明显游戏质量高了一个档次。


       这里再补充一下: 一旦你定义了<uses-sdk android:minSdkVersion="4" />,就是限制1.5SDK的手机无法安装你的程序;


      OK,继续忙了,大家尝试下吧~

 

1.Screen size 屏幕实际尺寸。 
Android讲屏幕实际尺寸分为3个通用的尺寸。 
    
   2.Aspect ratio 长宽比 

   3.Resolution 分辨率 

   4.Density 密度 

   5.Density-independent pixel 密度无关的像素 

介绍:Adnroid1.6或以上SDK,在AndroidManifest.xml中提供新的一个元素<supports-screens>用于支持多屏幕机制。 
 <supports-screens  
           android:largeScreens="true"   是否支持大屏 
            android:normalScreens="true"  是否支持中屏 
            android:smallScreens="true"   是否支持小屏 
            android:anyDensity="true"     是否支持多种不同密度 
 />  

Android提供3种方式处理屏幕自适应 
 一.预缩放的资源(基于尺寸和密度去寻找图片) 
 1.如果找到相应的尺寸和密度,则利用这些图片进行无缩放小时。 
 2.如果没法找到相应的尺寸,而找到密度,则认为该图片尺寸为 "medium",利用缩放这个图片显示。 
 3.如果都无法匹配,则使用默认图片进行缩放显示。默认图片默认标配 "medium" (160)。 

 二.自动缩放的像素尺寸和坐标(密度兼容) 
 1.如果应用程序不支持不同密度android:anyDensity="false",系统自动缩放图片尺寸和这个图片的坐标。 
   (代码中体现) 
 2.对于预缩放的资源,当android:anyDensity="false",也不生效。 
 3.android:anyDensity="false",只对密度兼容起作用,尺寸兼容没效果 

 三.兼容模式显示在大屏幕,尺寸(尺寸兼容) 
 1.对于你在<supports-screens>声明不支持的大屏幕,而这个屏幕尺寸是normal的话,系统使用尺寸为     ("normal")和密度为("medium)显示。 
 2. 对于你在<supports-screens>声明不支持的大屏幕,而这个屏幕尺寸是larger的话,系统同样使用尺寸为                   ("normal")和密度为("medium)显示,不过会出现一层黑色的背景。不是居中显示。 

密度独立: 
 系统默认应用支持DIP单位的,三个使用DIP的地方: 
 1.加载资源时,使用DIP实现预缩放的资源。 
 2.在Layout使用DIP,系统自动完成缩放。 
 3.在应用程序中,自动缩放一些绝对像素。 
     (只有在android:anyDensity="false"生效)即屏幕自适应方式二 
 4.像素单位都使用DIP,文本单位使用SP 

最佳屏幕独立实践: 
 1.使用wrap_content, fill_parent 和使用dip作为像素单位in XML layout files。 
 2.避免使用AbsoluteLayout  
 3.在代码中,不要使用像素数字硬编码,而是要通过dip转换为px。 
      例子: 
    你使用手势分析器分析一个scroll手势,假如,你滚动的距离是16px。 
 1.在一个160dip的屏幕中,你实际移动距离 16px / 160dpi = 1/10th of an inch (or 2.5 mm) 
 2.在一个240dip的屏幕中,你实际移动距离 16px / 240dpi = 1/15th of an inch (or 1.7 mm) 
   // The gesture threshold expressed in dip  
   private static final float GESTURE_THRESHOLD_DIP = 16.0f;  
    // Convert the dips to pixels  
    final float scale = getContext().getResources().getDisplayMetrics().density;  
    mGestureThreshold = (int) (GESTURE_THRESHOLD_DIP * scale);  
 4.使用密度和/或尺寸特定资源(通过文件夹) 

关于预缩放或者自动缩放图片或9格图 
 1.系统是一定对会资源包下的图片进行合理的缩放。 
    例如:一张240x240高密度图片,显示在中密度的屏幕上,图片大小自动变为160x160。 
 2.你在API中不会得到被缩放后的图片尺寸,得到还是你原来图片的尺寸。 
 3.如果你不想系统自动帮你缩放图片,可以建立一个res/drawable-nodpi文件夹,存放你的图片。 
 4.也可以通过BitmapFactory.Options 完成系统自动缩放图片或9格图(在画图时)。 
 5.自动缩放图片比预缩放花费更多CPU,但是用更少内存(RAM or ROM ?)

 

 

一、相关概念

a)       android支持density的版本 
Android从1.6版本开始支持density(对应API Level 4)

b)       density 
density值表示每英寸有多少个显示点,比如240就是每英寸240个点,它是针对设备的属性,它是屏幕物理长宽的扩展,给屏幕设置为低密度显示的内容少,同样的条件下,密度小的屏幕显示同样的按钮看起来大,高密度的看起来小

c)       分辨率 
是整个屏是多少点,比如800x480,它是对于软件来说的显示单位,以px为单位的点

d)       设置density的效果 
不同density下屏幕分辨率信息,以480dip*800dip的WVGA为例 
density=120时 屏幕实际分辨率为240px*400px 
density=160时 屏幕实际分辨率为320px*533px 
density=240时 屏幕实际分辨率为480px*800px

二、相关代码及设置

a)       AndroidManifest.xml 
<supports-screens android:anyDensity="true"/> 
<uses-sdk android:minSdkVersion="4"></uses-sdk>

b)       资源目录名(android 2.0以后) 
res/xxx-hdpi    当density为240时,使用此目录下的资源 
res/xxx-mdpi    当density为160时,使用此目录下的资源 
res/xxx-ldpi    当density为120时,使用此目录下的资源 
res/xxx     不常后缀,为默认设置,同xxx-mdpi 
如果硬件相应的desity的目录不存在,系统会利用存在的density自动乘以系数计算出相应的density

c)       资源单位(layout xml文件中定义大小的单位)

                     i.              dp=dip=dx   ( Density independent pixel ) 
基于屏幕密度的抽象单位,布局时尽量使用单位dip,少使用px 
dip是 
应用用于定义UI的虚拟单位,用于说明与密度无关的尺寸和位置。 
dip点等价于160dpi密度中的一个物理点,密度由平台决定,换算公式如下 
pixels = dips * (density / 160)  160DPI的密度系数是1 
例如 240 dpi的屏幕,1dip点等于1.5个物理点

                  ii.              px 
设置的绝对点数, 如果使用更高density的系统, 控件就会变小

三、设置density 
设置系统变量hw.lcd.density,可设置density

四、实现density的关键源码

a)       BitmapFactory.java

b)       ComptibilityInfo.java




为了更好的让应用程序的界面能适应不同手机的屏幕大小,有时候我们在开发中使用相对于屏幕实际大小的方法来设定布局中各个空间的位置跟大小,通过下面的方法可以获得Android手机实际屏幕分辨率大小。


首先我们需要用到的是DisplayMetrics这个类,它可以为我们获得手机屏幕属性,这里将其所在类导入。
import android.util.DisplayMetrics; 

 

得到实例对象。
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm); 

 

得到手机屏幕高度:
dm.heightPixels;

 

得到手机屏幕宽度:
dm.widthPixels;

 

得到以上手机屏幕的高度跟宽度后,即可以通过这两个值按照比例还设定程序布局中空间的大小。

 

=========================

实现的程序如下:

 

在布局文件main.xml中添加一个TextView对象,一个Button对象。其中TextView对象用来显示获得的分辨率值,Button对象是当点击时获取分辨率。main.xml的代码如下:

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>     
  2. <LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"    
  3.     Android:orientation="vertical"    
  4.     Android:layout_width="fill_parent"    
  5.     Android:layout_height="fill_parent"    
  6.     >     
  7.    <TextView      
  8.       Android:id="@+id/tv"      
  9.       Android:layout_width="fill_parent"      
  10.       Android:layout_height="wrap_content"      
  11.       Android:text="手机分辨率为:"/>     
  12.     <Button     
  13.        Android:id="@+id/btnOK"    
  14.        Android:layout_width="fill_parent"    
  15.        Android:layout_height="wrap_content"    
  16.        Android:text="获取手机分辨率"/>     
  17. </LinearLayout>  

 

 

在TestActivity中的代码如下:

Java代码   收藏代码
  1. public class TestActivity extends Activity {     
  2.              
  3.     private TextView tv;     
  4.     private Button btn;     
  5.          
  6.     //获取手机屏幕分辨率的类     
  7.      private DisplayMetrics dm;     
  8.          
  9.     public void onCreate(Bundle savedInstanceState) {     
  10.         super.onCreate(savedInstanceState);     
  11.         setContentView(R.layout.main);      
  12.              
  13.         tv = (TextView)findViewById(R.id.tv);     
  14.         btn = (Button)findViewById(R.id.btnOK);     
  15.         btn.setOnClickListener(new View.OnClickListener() {     
  16.                  
  17.           public void onClick(View v) {     
  18.               dm = new DisplayMetrics();     
  19.           getWindowManager().getDefaultDisplay().getMetrics(dm);     
  20.                   //获得手机的宽度和高度像素单位为px     
  21.           String strPM = "手机屏幕分辨率为:" + dm.widthPixels+"* "+dm.heightPixels;     
  22.           tv.setText(strPM);     
  23.             }     
  24.         });     
  25.     }     
  26.       
  27. }  

 

 

运行程序后,当我们点击Button按钮时,可以看到下面的效果图:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值