zoukankan      html  css  js  c++  java
  • 动态获取屏幕尺寸

    android中获取屏幕的长于宽,参考了网上有很多代码,但结果与实际不符,如我的手机是i9000,屏幕大小是480*800px,得到的结果却为320*533

    结果很不靠谱,于是自己写了几行代码,亲测一下

    测试参数:

    测试环境: i9000(三星)

    物理屏幕:480*800px

    density :1.5

    测试代码:

    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);  


    结果如下:

    1. E/== MyScreenActivity ===================================  getDefaultDisplay( 8509): screenWidth=320; screenHeight=533  
    2. E/== MyScreenActivity ===================================  DisplayMetrics( 8509): xdpi=156.3077; ydpi=157.51938  
    3. E/== MyScreenActivity ===================================  DisplayMetrics( 8509): density=1.0; densityDPI=160  
    4. E/== MyScreenActivity ===================================  DisplayMetrics(111)( 8509): screenWidth=320; screenHeight=533  
    5. E/== MyScreenActivity ===================================  DisplayMetrics( 8509): xdpi=234.46153; ydpi=236.27907  
    6. E/== MyScreenActivity ===================================  DisplayMetrics( 8509): density=1.5; densityDPI=240  
    7. E/== MyScreenActivity ===================================  DisplayMetrics(222)( 8509): screenWidthDip=320; screenHeightDip=533  
    8. E/== MyScreenActivity ===================================  DisplayMetrics(222)( 8509): screenWidth=480; screenHeight=800  

    分析结果:

    在onDraw()方法中

    方法1和2,得到的结果都一致,均为320*533,明显不是测试机i9000的屏幕大小

    方法3,将方法1和2得到的结果,乘以density后,完美的480*800,perfect!

    注: density 大于1的情况下,需要设置targetSdkVersion在4-9之间,例如
    <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="10" />

    但是,这就说明方法3一定是通用的吗?

    回答是否定的,因为我也在模拟器、HTC G14物理机,以及ViewSonic、Galaxy平板上测试过,方法3在density=1.5时,放大了实际屏幕值,例如:HTC G14

    在HTC G14上,实际屏幕大小,直接通过dm.widthPixels、dm.heightPixels便得到了实际物理屏幕大小(540,960)

    导致无法通过一种通用的方法获取真实物理屏幕大小的原因,可能就是因为Android系统开源,不同的手机生产厂商没有统一的制造标准,来规定手机屏幕。

    仔细分析代码,发现问题出在代码:

    getWindowManager().getDefaultDisplay().getMetrics(dm)

    Initialize a DisplayMetrics object from this display's data.

    dm = getResources().getDisplayMetrics()

    Return the current display metrics that are in effect for this resource object. The returned object should be treated as read-only.

    测试源码

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

    网上看到在配置文件中加入:
    <supports-screens
    android:smallScreens="true"
    android:normalScreens="true"
    android:largeScreens="true"
    android:resizeable="true"
    android:anyDensity="true" />
    <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8" />
    这样的话,当前的Android程序就支持了多种分辨率,那么就可以得到正确的物理尺寸了。
    这3中方法都可以正确获取,我的htc320*480
    模拟机(240*400)(400*800)
    不用加最后的(int)(dm.widthPixels * density + 0.5f);
    3中方法都可以,总结一下
    (1)直接 int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
    int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
    (2)通过getResources()获取DisplayMetrics对象,
    DisplayMetrics dm = new DisplayMetrics();
    dm = getResources().getDisplayMetrics();
    screenWidth = dm.widthPixels;
    screenHeight = dm.heightPixels;
    (3)通过getWindowManager()获取
    dm = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dm);
    screenWidth = dm.widthPixels;
    screenHeight = dm.heightPixels;

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

    参考推荐:

    Android的计量单位px,in,mm,pt,dp,dip,sp

  • 相关阅读:
    Kubernetes-一文详解ServiceAccount与RBAC权限控制
    删除无用的docker镜像与容器
    How do I write one to many query in Dapper.Net?
    c# 使用反射Reflection的Emit实现动态创建元数据及可执行文件
    IE浏览器下bootStrap form-control input输入框不显示兼容性问题
    WPF控件从一个窗口移动到另一个窗口,特别适合实时刷新的
    添加/扫描显示二维码中的换行之【另类视野】
    各浏览器官方离线版下载地址
    CentOS挂载NTFS
    System.Data.SQLite.Core for .NET 5 Core manual reference
  • 原文地址:https://www.cnblogs.com/flyingsir/p/4111157.html
Copyright © 2011-2022 走看看