• Android DisplayMetrics 获取和屏幕相关的信息


    Android源码中是这样来描述DisplayMetrics的。

    /**
     * A structure describing general information about a display, such as its
     * size, density, and font scaling.
     * <p>To access the DisplayMetrics members, initialize an object like this:</p>
     * <pre> DisplayMetrics metrics = new DisplayMetrics();
     * getWindowManager().getDefaultDisplay().getMetrics(metrics);</pre>
     */
    

    按照DisplayMetrics注释中的那样,我们直接写个例子来测试下,就什么都明白了。我用的是小米3:

            DisplayMetrics metrics = new DisplayMetrics();
            getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
    
            /**
             * The logical density of the display.  This is a scaling factor for the
             * Density Independent Pixel unit, where one DIP is one pixel on an
             * approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen),
             * providing the baseline of the system's display. Thus on a 160dpi screen
             * this density value will be 1; on a 120 dpi screen it would be .75; etc.
             *
             * <p>This value does not exactly follow the real screen size (as given by
             * {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of
             * the overall UI in steps based on gross changes in the display dpi.  For
             * example, a 240x320 screen will have a density of 1 even if its width is
             * 1.8", 1.3", etc. However, if the screen resolution is increased to
             * 320x480 but the screen size remained 1.5"x2" then the density would be
             * increased (probably to 1.5).
             *
             * density 是逻辑上的屏幕密度,约定在160dpi的设备上,1px=1dip。
             * density = densityDpi / 160
             *
             * @see #DENSITY_DEFAULT
             */
            float density = metrics.density;
            /**
             * The screen density expressed as dots-per-inch.  May be either
             * {@link #DENSITY_LOW}, {@link #DENSITY_MEDIUM}, or {@link #DENSITY_HIGH}.
             * densityDpi 表示每英寸的点数(并不是像素数)
             */
            int densityDpi = metrics.densityDpi;
            /**
             * The absolute height of the display in pixels.
             * 屏幕的绝对高度,以像素为单位。
             */
            int heightPixels = metrics.heightPixels;
            /**
             * The absolute width of the display in pixels.
             * 同样,这个是屏幕的绝对宽度,以像素为单位。
             */
            int widthPixels = metrics.widthPixels;
    
            /**
             * The exact physical pixels per inch of the screen in the X dimension.
             * 横向每一英寸确切的物理像素,我们可以尝试通过这个值和widthPixels 来计算屏幕的宽度英寸。
             */
            float xdpi = metrics.xdpi;
            /**
             * The exact physical pixels per inch of the screen in the Y dimension.
             * 横向每一英寸确切的物理像素,我们可以尝试通过这个值和heightPixels 来计算屏幕的高度英寸。
             */
            float ydpi = metrics.ydpi;
            /**
             * A scaling factor for fonts displayed on the display.  This is the same
             * as {@link #density}, except that it may be adjusted in smaller
             * increments at runtime based on a user preference for the font size.
             *  scaledDensity 这个值从上面的注释看,是和字体相关的factor,通常情况下这个值和density是相等的,但是假如用户手动的调整了
             *  系统字体的大小,那么这个值就有可能改变(以小米3为例,标准字体,这个值=3,最大字体这个值=3.25)。
             *  因此现在很多情况下,我们把字体单位写成dp,尽管Google建议的字体让写成sp。
             */
            float scaledDensity = metrics.scaledDensity;
            LogUtil.logd(TAG, "metrics.density = " + density);
            LogUtil.logd(TAG, "metrics.densityDpi = " + densityDpi);
            LogUtil.logd(TAG, "metrics.heightPixels = " +heightPixels);
            LogUtil.logd(TAG, "metrics.widthPixels = " +widthPixels);
            LogUtil.logd(TAG, "metrics.xdpi = " +xdpi);
            LogUtil.logd(TAG, "metrics.ydpi = " +ydpi);
            LogUtil.logd(TAG, "metrics.scaledDensity = " +scaledDensity);
    
            //来计算手机是几英寸的
            float pixelsToDipWidth  = widthPixels / xdpi;
            float pixelsToDipHeight = heightPixels / ydpi;
            LogUtil.logd(TAG, "pixelsToDipWidth = " + pixelsToDipWidth);
            LogUtil.logd(TAG, "pixelsToDipHeight = " + pixelsToDipHeight);
            double mobileInch = Math.sqrt(pixelsToDipHeight * pixelsToDipHeight + pixelsToDipWidth * pixelsToDipWidth);
            //我用的小米3,得到的值是4.917646062686045
            LogUtil.logd(TAG, "mobileInch = " + mobileInch);

    通过这个例子,我们明白了dip及px代表着什么,我们就可以来写出dip与px相互转换的方法。(dip = px / density)

        /**
         * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
         */
        public static int dip2px(Context context, float dpValue) {
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }
    
        /**
         * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
         */
        public static int px2dip(Context context, float pxValue) {
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (pxValue / scale + 0.5f);
        }

    上面 加的这个0.5f的原因,Google官方文档中其实有介绍:

    Then add 0.5f to round the figure up to the nearest whole number, when converting to an integer.

    说白了就是为了四舍五入。。。

    比如我上面的例子:

    mobileInch = 4.917646062686045 ,我+0.5f(=5.417646062686045),然后再取整之后,就得到5。


  • 相关阅读:
    python-函数-实现学生管理系统,完成对学员的增,删,改,查和退出学生管理系统。
    python-函数-定义一个函数,实现两个数四则运算,要注意有3个参数,分别是运算符和两个运算的数字.
    Python-函数-continue、break、pass
    python-函数-写函数,接收n个数字,求这些数字的和
    python-函数-写函数,检查传入的字符串是否含有空字符串,返回结果,包含空字符串返回True,不包含返回False
    python-函数-写函数,判断用户传入的对象(列表)长度是否大于5,如果大于5,那么仅保留前五个长度的内容并返回。不大于5返回本身
    Python-函数-写函数,获取传入列表的所有奇数位索引对应的元素,并将其作为新列表返回
    PHP解析json字符串问题
    《算法技术手册》-Algorithms in a nutshell 作者: George T. Heineman
    PHP面向对象设计总结
  • 原文地址:https://www.cnblogs.com/zhouliweiblog/p/5142863.html
Copyright © 2020-2023  润新知