关于屏幕的那些事

Android将设备屏幕归类为两种常规属性:尺寸和分辨率。你应该想到你的app会被安装在各种屏幕尺寸和分辨率的设备中。这样,你的app就应该包含一些可选资源,针对不同的屏幕尺寸和分辨率,来优化你的app外观。

有4种普遍尺寸:小(small),普通(normal),大(large),超大(xlarge)
4种普遍分辨率:低精度(ldpi), 中精度(mdpi), 高精度(hdpi), 超高精度(xhdpi)

为了适配屏幕,你应该为4种普遍分辨率:低,中,高,超高精度,都提供相适配的bitmap资源。这能帮助你在所有屏幕分辨率中都能有良好的画质和效果。

要生成这些图像,你应该从原始的矢量图像资源着手,然后根据下列尺寸比例,生成各种密度下的图像。

  • xhdpi: 2.0
  • hdpi: 1.5
  • mdpi: 1.0 (基准)
  • ldpi: 0.75

这意味着,如果你针对xhdpi的设备生成了一张200x200的图像,同样的你应该为hdpi生成150x150,为mdpi生成100x100, 和为ldpi生成75x75的图片资源。

然后,将这些文件放入相应的drawable资源目录中:

MyProject/
res/
drawable-xhdpi/

      awesomeimage.png        

- drawable-hdpi/

      awesomeimage.png  

- drawable-mdpi/

     awesomeimage.png   

- drawable-ldpi/

     awesomeimage.png

任何时候,当你引用@drawable/awesomeimage时系统会根据屏幕的分辨率选择恰当的bitmap。

  • Note:低密度(ldpi)资源是非必要的,当你提供了hdpi的图像,系统会把hdpi的图像按比例缩小一半,去适配ldpi的屏幕。

参考网址:官网

好了,不废话了,本文主要就是讲些关于屏幕的技巧:

获取屏幕宽高

  1. 环境测试:

    这里写图片描述

    通常很多人测试获取屏幕尺寸都用如下方式返回一个 DisplayMetrics 对象,然后通过 .widthPixels .heightPixels 获得

    方法一:

    public static DisplayMetrics getDisplayMetrics(Activity activity) {
        DisplayMetrics dm = new DisplayMetrics();
        Display display = activity.getWindowManager().getDefaultDisplay();
        display.getMetrics(dm);
        return dm;
    }

    环境测试结果如下:
    768*1184

    方法二(已弃用):

    int screenWidth = activity.getWindowManager().getDefaultDisplay().getWidth(); // 屏幕宽(像素,如:480px)
    int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight(); // 屏幕高(像素,如:800p)
    Log.i("real px4", "screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);

    环境测试结果如下:
    screenWidth=768; screenHeight=1184

    部分参数测试输出:

        DisplayMetrics dm = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
        density = dm.density; // 屏幕密度(像素比例:0.75/1.0/1.5/2.0)
        densityDPI = dm.densityDpi; // 屏幕密度(每寸像素:120/160/240/320)
    
        xdpi = dm.xdpi;
        ydpi = dm.ydpi;
    
        Log.e("real px8", "xdpi=" + xdpi + "; ydpi=" + ydpi);
        Log.e("real px9", "density=" + density + "; densityDPI=" + densityDPI);
        int screenWidthPx = dm.widthPixels; // 屏幕宽(px,如:768px)
        int screenHeightPx = dm.heightPixels; // 屏幕高(px,如:1184px)
        Log.e("real px10", "screenWidthPx=" + screenWidthPx + "; screenHeightPx=" + screenHeightPx);
    
        int screenWidthDp = (int) (dm.widthPixels / density + 0.5f); // 屏幕宽(dip,如:384dip)
        int screenHeightDp = (int) (dm.heightPixels / density + 0.5f); // 屏幕宽(dip,如:592dip)
        Log.e("real px11", "screenWidthDp=" + screenWidthDp + "; screenHeightDp=" + screenHeightDp);

    结果:

    我们常用的px2dp方法(px值/密度+0.5f):

    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;  // 屏幕密度
        return (int) (pxValue / scale + 0.5f);
    }

    看到这里,以后面试官问你px和dp的转换,你还会忘记吗?

    回到正题,刚刚方法获取的屏幕高度都为1184 ,对比测试环境的1280是不是少了很大的值?

    那么我们如何获取屏幕的真正高度,获取了又有很用?

    获取真实高度(反射原理,不懂反射的可以看我blog:Java反射详解):

    public void getRealHeight() {
        Display display = this.getWindow().getWindowManager().getDefaultDisplay();
        DisplayMetrics metrics = new DisplayMetrics();
        display.getMetrics(metrics);
        int width =  metrics.widthPixels;
        int height = metrics.heightPixels;
        if (Build.VERSION.SDK_INT >= 17) {
            try {
                android.graphics.Point realSize = new android.graphics.Point();
                Display.class.getMethod("getRealSize",   android.graphics.Point.class).invoke(display, realSize);
                height = realSize.y;
            } catch (Exception ignored) {
            }
        }
        Log.v("real px", "display(fullscreen) =" + width + "*" + height);
    }

    结果:
    这里写图片描述

获取控件宽高

未完待续...

你可能感兴趣的:(android,分辨率,屏幕大小,屏幕尺寸)