說起來慚愧,學(xué)安桌這么久才總結(jié)這個東西.并且網(wǎng)上已經(jīng)有很多類似的總結(jié)了.這個總結(jié)權(quán)當給加深記憶,以及給大家參考.
先解釋下上述各個名詞
px(pixels): 像素->
組成畫面的最小單位,由紅藍綠(RGB)三原色組成,像素的大小是沒有固定長度的,具體長度由具體設(shè)備決定.
dpi(dots per inch 每英寸點數(shù))和 ppi(pixels per inch 每英寸像素數(shù))->
可認為是同樣的單位,區(qū)別只在你是以點為最小單位還是以像素為最小單位(點一般是用于打印物體計算的)
dip/dp (device independent pixels)設(shè)備獨立像素,與設(shè)備屏幕有關(guān),是安卓開發(fā)用的長度單位
sp (scale pixel 像素縮放)拒名,安卓開發(fā)用的字體大小單位。
inch(英寸) 1inch=2.54cm
dpi/ppi的計算方法
在我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())
}
//打印結(jié)果
01-29 12:44:23.794 8903-8903/? E/CalculateDPI: 423.6360097854721
01-29 12:44:23.794 8903-8903/? E/SystemDPI: 420
可見 系統(tǒng)提供的DPI的值并非最正確的.在系統(tǒng)中使用的全部都是系統(tǒng) dpi修械,沒有使用物理 dpi叁巨,也獲取不到物理 dpi停团。
Android 中內(nèi)置了幾個默認的 Dpi 喊递,根據(jù)分辨率查表即可得到該手機的系統(tǒng)DPI,不過系統(tǒng)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的數(shù)學(xué)定義:1dp定義為屏幕密度值為160dpi時的1px
因此使用dp單位只能保證控件大小通過像素密度進行一定比例的縮放,但是顯示效果并不保證一樣.
比如同樣的320dp的控件 在720x1280分辨率下顯示效果如上圖
而在 320x480 分辨率下顯示效果如下圖
sp與dp類似,但是可以根據(jù)用戶的字體大小首選項進行縮放虹茶。
當文字尺寸是“正呈判剑”時1sp=1dp,而當文字尺寸是“大”或“超大”時蝴罪,1sp>1dp董济。
一般情況下可認為sp=dp。
對displayMetrics里面幾個值的解釋
densityDpi 即系統(tǒng)DPI
density=scaledDensity 系統(tǒng)DPI/基準DPI(160) 縮放因子
heightPixels 與 widthPixels 長寬有效像素,heightPixels會減去導(dǎo)航欄高度,并不是屏幕的真實像素大小
獲取屏幕真實像素大小使用windowManager.defaultDisplay.getRealSize()
dp px互轉(zhuǎn)方法,由上面的描述已經(jīng)知道怎么轉(zhuǎn)化了
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作用是在強制轉(zhuǎn)化時進行4舍5入,比如(int)(4.4+0.5)=4 而(int)(4.5+0.5) = 5
參考資料:
http://www.reibang.com/p/584ac569ffc3
http://blog.qiji.tech/archives/2581