Android之px/dpi/dip/dp/density/DisplayMetrics和屏幕適配

Android之px/dpi/dip/dp/density/DisplayMetrics和屏幕適配

文章鏈接:http://blog.csdn.net/qq_16628781/article/details/69397950

友情鏈接:http://blog.csdn.net/qq_16628781/article/details/53488386

知識點

  1. px、DPI、density和dip/dp的簡介;
  2. Android系統設置的dpi和dp的關係+實例說明;
  3. layout_weight/權重/百分比適配佈局;
  4. DisplayMetrics的說明及使用;
  5. 新名詞記錄{DisplayMetrics:描述屏幕密度、大小和字體縮放值等信息的類;}


首先來幾個概念熱熱身。
屏幕尺寸:屏幕對角線的長度。不是很清楚爲毛這麼量,可能是看起來更大吧。

分辨率:長和寬兩個方向有的像素點的乘積。例如當下最火的4k電視,那麼在寬上面有超過4千個像素點,高上面也有3千多個,那麼乘積就是120萬+的點來呈現畫面。手機同理。

px:就是長寬方向上的最小單位的一個發光點。

DPI:dots per inch。就是一英尺(約2.54平方)距離上面共有多少個像素點。

Density:一英尺(2.54* 2.54)面積距離上面共包含多少個像素點。例如,320 * 240的屏幕,那麼Dpi = 320 / 2 = 240 / 1.5 = 160。

dip/dp:Density independent pixels,設備獨立像素。每個設備可能都是不同的值。我們也用得最多。這裏重點用來理解。

Android默認的dpi

ldpi:分辨率:240x320;系統dpi:120;基準比例:120 / 160 = 0.75。

mdpi:分辨率:320x480;系統dpi:160;基準比例:160 / 160 = 1。

ldpi:分辨率:480x800;系統dpi:240;基準比例:240/ 160 = 1.5。

ldpi:分辨率:720x1280;系統dpi:320;基準比例:360 / 160 = 2。

ldpi:分辨率:1080x1920;系統dpi: 480;基準比例: 480 / 160 = 3。

看這麼多,蒙圈了吧?!舉個栗子?

這裏給一個例子來解釋一下。重複一下—dp/dip是和屏幕密度(DPI)無關的單位。

在1920 * 1080分辨率的手機上,默認就使用480的dpi。那麼我們的基準比例就是480/160=3。

例如我定義一個textview的
layout_width=” 200dp “,layout_height=”100dp”。

如果在1920 * 1080分辨率的設備上,寬爲:200 * 3 = 600px,600像素來顯示;高爲:100 * 3 = 300px,300px來顯示。

但是,如果設備屏幕是720px * 1280px的呢?那麼寬200dp * 100dp的就要400px * 200px來顯示。

如果設備屏幕是480px * 800px,就需要300px * 150px來顯示。

如果設備屏幕是320px * 480px,就需要200px * 150px來顯示。

如果設備屏幕是240px * 320px,就需要150px * 75px來顯示。

是不是一目瞭然,上面的各個數學計算。


但是我在這裏弄一個比較極端的情況。假如我弄一個寬度爲500dp * 400dp的TextView呢?那麼情況會是怎樣的呢?

這裏反過來,從小分辨率屏幕說起。

如果設備屏幕240px * 320px,就需要375px * 300px來顯示。但是看到,設備的屏幕就只有240px寬,那麼就顯示不下了。
即使是1920 * 1080的設備屏幕,也需要1500px * 1200px的來顯示,結果也是不能夠顯示滴。

那麼,這裏就引入一個問題:我應該如何來進行佈局呢?或者說更好的屏幕適配?
如今,Android陣營的屏幕碎片化真的是太嚴重了,據不完全統計,Android設備的屏幕有2萬多種,這是一個多麼可怕的數據。所以我們在開發的時候,就需要做屏幕的適配了,絕對不能夠佈局的控件跑到屏幕外面去了,不然就鬧大了。

也許有童鞋就會說了,我按着最小的屏幕分辨率的來適配,那麼接着大的屏幕就完全可以裝下去了。這是一種解決方案。這並不能解決問題。這也許是在寬高只有1至2個控件的基礎上。但是如果我的控件多到4,5,6個,那麼你還能過寫死每一個控件的寬度麼?如果寫死了,那麼在高分辨率的屏幕上看到的也許就只佔了一點點的寬度。這樣的佈局就太難看了吧。

那麼如何來搞呢?如何更好地解決這個問題呢?

目前最推薦的方式是百分比(權重)佈局,或者是layout_weight這個屬性。

注意:如果要使layout_weight生效,那麼在橫向的layout _width=”0dp”,或者在layout _height=”0dp”才能夠生效。

這個屬性的使用比較簡單:layout_weight值越大,對應的寬高就越大。我在這裏就不一一講解了。


DisplayMetrics類

DisplayMetrics類,是系統提供給我們的用以獲取設備屏幕的一個API。系統推薦的用法:DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

方法一:

DisplayMetrics metrics = new DisplayMetrics();
Display display = activity.getWindowManager().getDefaultDisplay();
display.getMetrics(metrics);

方法二:

DisplayMetrics metrics=activity.getResources().getDisplayMetrics(); 

方法三:

Resources.getSystem().getDisplayMetrics();

下面再說下如何來獲取屏幕的各個信息。

public static void getDisplayMetrics(Activity activity) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        float xdpi = displayMetrics.xdpi; //物理屏幕上x軸方向每英寸(2.54cm)的像素
        float ydpi = displayMetrics.ydpi; //y軸
        float density = displayMetrics.density; //屏幕密度,和像素px無關
        int densityDpi = displayMetrics.densityDpi; //沒英寸距離具有多少個像素點
        int heightPixels = displayMetrics.heightPixels; //屏幕的高度,單位爲px
        int widthPixels = displayMetrics.widthPixels; //屏幕的寬度,單位爲px
        float scaledDensity = displayMetrics.scaledDensity; //爲字體適配的縮放單位,根據系統字體來縮放字體大小
        displayMetrics.setToDefaults(); //將上述值設置成默認值
//        displayMetrics1.setTo(displayMetrics2); //設置displayMetrics2的值複製到displayMetrics1中去
    }

可以根據自己的需要獲取相應的信息即可。

其中densityDpi有3個取值,分別是DENSITY_ LOW = 120;DENSITY_ MEDIUM = 160;DENSITY_HIGH = 240;


總結

關於屏幕適配,我現在用的最多的也是“權重”/“百分比”/“layout_weight”來做,而且可以搜索到,現在主流的機型都是4.5寸以上的了,或者說是5.0寸以上,對於某些4.5以下的屏幕,我們可以選擇性的放棄,不再要求適配。這裏的原因有不少,比如APP主打受衆爲年輕人,那麼他們設備的屏幕、性能和Android版本可能都是比較好的,那麼就可以不需要進行適配5.0以下的了。

適配的路子,任重而道遠啊,需要不停地努力向前。共勉

如有任何問題,請及時與我聯繫,謝謝!

發佈了135 篇原創文章 · 獲贊 70 · 訪問量 51萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章