概述
可能大家都知道,一款app要想適配儘可能多的手機,在寫佈局檔案的時候都會使用dp來代替px. 如果遇到需要特別處理的則寫在指定資料夾(如:values-sw600dp, values-sw720dp-land)下面的dimens.xml中,但是具體到1dp在螢幕上能顯示多大,一張100*100px的圖片在不同資料夾(drawable-xhdpi, drawable-xxhdpi)中能顯示多大,佔用多少記憶體可能相對較模糊,這篇文章就來講講他們之間的關係
概念
在搞清楚他們的關係之前,還是先來這幾個名稱的概念
解析度
手機的螢幕上能容納的畫素點。
比如1080*1920(俗稱1080p),就是指橫向能容納1080個畫素點,縱向能容納1920個畫素點
dpi
是Dots Per Inch的縮寫,翻譯過來就是每英寸(Inch)有多少點。來舉個栗子
在AS裡面建立模擬器的時候,會出現上圖來選擇裝置。
其中Size就是指的手機對角線的長度,單位是英寸("),Nexus5為例,對角線上的畫素點有:sqrt(1080 1080 + 1920 1920) = 2202.907,那麼對角線上每英寸有的畫素點就是:2202.907 / 4.95 = 445.03,那nexus5的dpi就是445.03咯? 其實不是,但是也是。
實際上nexus5的dpi就是445.03,但是在android中使用的時候,會根據如下範圍標準來
所以nexus5會顯示為xxhdpi(480dpi)
每種通用的密度都涵蓋的是密度範圍,也就是說2部都是480dpi的手機,其實際的dpi有可能不一樣.
dp
所有的android開發在定義長寬的時候都在使用dp,那麼dp到底是什麼呢?
要講清楚這個還得從android歷史開始。
第一代 Android 裝置 (T-Mobile G1) 的螢幕是採用的HVGA 螢幕(在 Android 1.6 之前,這是 Android 支援的唯一螢幕配置),這個螢幕上1dp=1px,並且是被歸為mdpi型別,從此,這個就成為了android的最初始標準。隨著不同廠商的加入,越來越多的不同dpi裝置出現,於是有了下面這個標準
ldpi | mdpi | hdpi | xhdpi | xxhdpi | xxxhdpi |
---|---|---|---|---|---|
0.75px | 1px | 1.5px | 2px | 3px | 4px |
這是怎麼來的呢?以xxhdpi來說,因為xxhdpi是歸為480dpi的一類裝置,是原始標準160dpi的2.5倍,所以1dp就對應2.5px
T-Mobile G1的硬體引數如下:
螢幕尺寸:3.2 寸(8.1 釐米)
解析度:320 x 480(HVGA)
計算出dpi = 180.27,所以歸為mdpi類
顯示大小
就是一個view顯示在螢幕上有多大,這個沒什麼好說的.
小結
要記住上面的關係可能很難,還好可以通過程式碼來獲取值,我們只要記住這幾個值是什麼意思就可以了。
先來看如何獲取dpi
float dpi = context.getResources().
getDisplayMetrics().densityDpi;複製程式碼
這個值就會是160.0 240.0 320.0這些值.
那如何獲取1dp對應著多少px呢?可以通過如下方式
float scale = context.getResources().
getDisplayMetrics().density;複製程式碼
這個值就是0.75 1.0 1.5這些值。
比如在hdpi上,1dp=1.5px,但這其實是佔有2個畫素的。所以在真正編碼的時候會用以下方式來做轉換
// The gesture threshold expressed in dp (定義的16dp的值)
private static final float GESTURE_THRESHOLD_DP = 16.0f;
// Get the screen's density scalefinal (獲取縮放比例)
float scale = getResources().density;
// Convert the dps to pixels, based on density scale (定義的值 * 比例 + 0.5f)
mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);複製程式碼
這裡加0.5是為了將該數字四捨五入到最接近的整數。
顯示大小
那麼,同一張圖,在不同的資料夾,同一個手機上會有什麼表現呢?
以一個144*144px的icon圖示(放在drawable-xxxhdpi目錄下),在xxhdpi密度的手機為例。用如下程式碼進行測試
//imageView都是wrap_content屬性, src=144*144px的icon圖示
ImageView imageView = (ImageView)findViewById(R.id.img);
imageView.post(new Runnable() {
@Override
public void run() {
Log.i("hly", "img: " + imageView.getWidth() + " " + imageView.getHeight());
}
});複製程式碼
這裡直接給出答案: 108px 【144 * (480 / 640)】
根據該文可以得出,計算公式是:
最終顯示畫素 = 原始畫素 * (顯示裝置dpi / 放置資料夾對應dpi)複製程式碼
這也就是如果對應資料夾裡面沒有圖片的時候,顯示預設圖片大小不一致的原因。
總結
也沒啥好總結的了,想要熟悉這些關係,需要先記住基準尺寸mdpi- 160dpi。
以上
歡迎關注公眾號