安桌开发中 px dpi(ppi) dip(dp) sp 的一些总结

说起来惭愧,学安桌这么久才总结这个东西.并且网上已经有很多类似的总结了.这个总结权当给加深记忆,以及给大家参考.


先解释下上述各个名词

px(pixels): 像素->
组成画面的最小单位,由红蓝绿(RGB)三原色组成,像素的大小是没有固定长度的,具体长度由具体设备决定.

dpi(dots per inch 每英寸点数)和 ppi(pixels per inch 每英寸像素数)->
可认为是同样的单位,区别只在你是以点为最小单位还是以像素为最小单位(点一般是用于打印物体计算的)

dip/dp (device independent pixels)设备独立像素,与设备屏幕有关,是安卓开发用的长度单位

sp (scale pixel 像素缩放),安卓开发用的字体大小单位。

inch(英寸) 1inch=2.54cm


dpi/ppi的计算方法


image.png

在我5.2英寸虚拟机上运行以下代码

    private fun calculatePPI(){
        val point = Point()
        windowManager.defaultDisplay.getRealSize(point)//获取屏幕真实分辨率
        Log.e("CalculateDPI",(Math.sqrt((point.x*point.x+point.y*point.y).toDouble())/5.2f).toString())
        Log.e("SystemDPI",resources.displayMetrics.densityDpi.toString())
    }
//打印结果
01-29 12:44:23.794 8903-8903/? E/CalculateDPI: 423.6360097854721
01-29 12:44:23.794 8903-8903/? E/SystemDPI: 420

可见 系统提供的DPI的值并非最正确的.在系统中使用的全部都是系统 dpi,没有使用物理 dpi,也获取不到物理 dpi。

Android 中内置了几个默认的 Dpi ,根据分辨率查表即可得到该手机的系统DPI,不过系统DPI可以给修改。

DPI类型 分辨率 DPI dp px
ldpi 240x320 120 1 0.75
mdpi(基准) 320x480 160 1 1
hdpi 480x800 240 1 1.5
xhdpi 720x1280 320 1 2
xxhdpi 1080x1920 480 1 3
Nexus 6/6p 1440x2560 560 1 3.5

dp的数学定义:1dp定义为屏幕密度值为160dpi时的1px

image.png

因此使用dp单位只能保证控件大小通过像素密度进行一定比例的缩放,但是显示效果并不保证一样.

安桌开发中 px dpi(ppi) dip(dp) sp 的一些总结_第1张图片
image.png
安桌开发中 px dpi(ppi) dip(dp) sp 的一些总结_第2张图片
image.png

比如同样的320dp的控件 在720x1280分辨率下显示效果如上图
而在 320x480 分辨率下显示效果如下图


sp与dp类似,但是可以根据用户的字体大小首选项进行缩放。
当文字尺寸是“正常”时1sp=1dp,而当文字尺寸是“大”或“超大”时,1sp>1dp。
一般情况下可认为sp=dp。


对displayMetrics里面几个值的解释
densityDpi 即系统DPI
density=scaledDensity 系统DPI/基准DPI(160) 缩放因子
heightPixels 与 widthPixels 长宽有效像素,heightPixels会减去导航栏高度,并不是屏幕的真实像素大小
获取屏幕真实像素大小使用windowManager.defaultDisplay.getRealSize()

dp px互转方法,由上面的描述已经知道怎么转化了


image.png
image.png
   fun dip2px(context: Context, dpValue: Float): Int {
        val scale = context.resources.displayMetrics.density
        return (dpValue * scale + 0.5f).toInt()
    }

    fun px2dip(context: Context, pxValue: Float): Int {
        val scale = context.resources.displayMetrics.density
        return (pxValue / scale + 0.5f).toInt()
    }

//加的0.5作用是在强制转化时进行4舍5入,比如(int)(4.4+0.5)=4 而(int)(4.5+0.5) = 5

参考资料:
https://www.jianshu.com/p/584ac569ffc3
http://blog.qiji.tech/archives/2581

你可能感兴趣的:(安桌开发中 px dpi(ppi) dip(dp) sp 的一些总结)