Android 获取屏幕尺寸与密度

    

Android 取屏幕尺寸与密度

 

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

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

 

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

 

  在一个ActivityonCreate方法中,写入如下代


        DisplayMetrics metric = newDisplayMetrics();
        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)


    但是,需要注意的是,在一个低密度的小屏手机上,仅靠上面的代码是不能获取正确的尺寸的。比如说,一部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程序就支持了多种分辨率,那么就可以得到正确的物理尺寸了。

 

 

1.     // 获取屏幕密度(方法1)  

2.    int screenWidth  = getWindowManager().getDefaultDisplay().getWidth();       // 屏幕宽(像素,如:480px)  

3.    int screenHeight = getWindowManager().getDefaultDisplay().getHeight();      // 屏幕高(像素,如:800p)  

4.      

5.    Log.e(TAG + "  getDefaultDisplay", "screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);  

6.      

7.      

8.     // 获取屏幕密度(方法2)  

9.    DisplayMetrics dm = new DisplayMetrics();  

10. dm = getResources().getDisplayMetrics();  

11.   

12. float density  = dm.density;        // 屏幕密度(像素比例:0.75/1.0/1.5/2.0)  

13. int densityDPI = dm.densityDpi;     // 屏幕密度(每寸像素:120/160/240/320)  

14. float xdpi = dm.xdpi;             

15. float ydpi = dm.ydpi;  

16.   

17. Log.e(TAG + "  DisplayMetrics", "xdpi=" + xdpi + "; ydpi=" + ydpi);  

18. Log.e(TAG + "  DisplayMetrics", "density=" + density + "; densityDPI=" + densityDPI);  

19.   

20. screenWidth  = dm.widthPixels;      // 屏幕宽(像素,如:480px)  

21. screenHeight = dm.heightPixels;     // 屏幕高(像素,如:800px)  

22.   

23. Log.e(TAG + "  DisplayMetrics(111)", "screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);  

24.   

25.   

26.   

27.  // 获取屏幕密度(方法3)  

28. dm = new DisplayMetrics();  

29. getWindowManager().getDefaultDisplay().getMetrics(dm);  

30.   

31. density  = dm.density;      // 屏幕密度(像素比例:0.75/1.0/1.5/2.0)  

32. densityDPI = dm.densityDpi;     // 屏幕密度(每寸像素:120/160/240/320)  

33. xdpi = dm.xdpi;           

34. ydpi = dm.ydpi;  

35.   

36. Log.e(TAG + "  DisplayMetrics", "xdpi=" + xdpi + "; ydpi=" + ydpi);  

37. Log.e(TAG + "  DisplayMetrics", "density=" + density + "; densityDPI=" + densityDPI);  

38.   

39. int screenWidthDip = dm.widthPixels;        // 屏幕宽(dip,如:320dip)  

40. int screenHeightDip = dm.heightPixels;      // 屏幕宽(dip,如:533dip)  

41.   

42. Log.e(TAG + "  DisplayMetrics(222)", "screenWidthDip=" + screenWidthDip + "; screenHeightDip=" + screenHeightDip);  

43.   

44. screenWidth  = (int)(dm.widthPixels * density + 0.5f);      // 屏幕宽(px,如:480px)  

45. screenHeight = (int)(dm.heightPixels * density + 0.5f);     // 屏幕高(px,如:800px)  

46.   

47. Log.e(TAG + "  DisplayMetrics(222)", "screenWidth=" + screenWidth + "; screenHeight=" + screenHeight); 

 

 

重中之重:

density值表示每英寸有多少个显示点,与分辨率是两个不同的概念:

Android主要有以下几种屏:

QVGA和WQVGA屏density=120;

HVGA屏density=160;

WVGA屏density=240;

下面以480dip*800dip的WVGA(density=240)为例,详细列出不同density下屏幕分辨率信息:

当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=240时使用hdpi标签的资源
当屏幕density=160时,使用mdpi标签的资源
当屏幕density=120时,使用ldpi标签的资源。
不加任何标签的资源是各种分辨率情况下共用的。
建议:布局时尽量使用单位dip,少使用px。

device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值