基本定義
PPI(Pixels per inch):每英寸所擁有的像素數,即像素密度。
DPI(dots per inch):即每英寸上,所能印刷的網點數,一般稱為像素密度。ppi計算公式:ppi = 屏幕對角線像素數/屏幕對角線英寸數,通過勾股定理計算屏幕對角線像素數。
Screen Size(屏幕尺寸):手機屏幕尺寸大小,如3英寸、4英寸、4.3英寸、5.7英寸,指的是對角線的長度。
DIP(device independent pixel):即dip/dp,設備獨立像素。 1px = 1dpdensity(由dpi決定)
Resolution(分辨率):指手機屏幕垂直和水平方向上的像素個數。eg分辨率480800,指該設備垂直方向有800個像素點,水平方向有480個像素點。
px(Pixel像素):相同像素的ui,在不同分辨率的設備上效果不同。在小分辨率設備上會放大導致失真,大分辨率上被縮小。
安卓常見DPI
Android Design里把主流設備的 dpi 歸成了四個檔次:120 dpi、160 dpi、240 dpi、320 dpi,具體見如下表格。
實際開發當中,我們經常需要對這幾個尺寸進行相互轉換(比如先在某個分辨率下完成設計,然后縮放到其他尺寸微調后輸出),一般按照 dpi 之間的比例即 2:1.5:1:0.75 來給界面中的元素來進行尺寸定義。
也就是說如果以 160 dpi 作為基準的話,只要尺寸的 DP 是 4 的公倍數,XHDPI 下乘以 2,HDPI 下乘以 1.5,LDPI 下乘以 0.75 即可滿足所有尺寸下都是整數 pixel 。但假設以 240 dpi 作為標準,那需要 DP 是 3 的公倍數,XHDPI 下乘以 1.333,MDPI 下乘以 0.666 ,LDPI 下除以 2。而以 LDPI 和 XHDPI 為基準就更復雜了。同時第一款Android設備(HTC的T-Mobile G1)是屬于160dpi的。鑒于以上各種原因,標準dpi=160
dpi | density | 分辨率 | |
---|---|---|---|
ldpi | 120dpi | 0.75 | 240*320px |
mdpi | 160dpi | 1 | 320*480px |
hdpi | 240dpi | 1.5 | 480*800px |
xhdpi | 320dpi | 2 | 720*1280px |
xxhdpi | 480dpi | 3 | 1080*1920px |
dp的官方說明
谷歌官方對dp的解釋如下:
A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way.
The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a "medium" density screen. At runtime, the system transparently handles any scaling of the dp units, as necessary, based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels. You should always use dp units when defining your application's UI, to ensure proper display of your UI on screens with different densities.
簡單來說,以160dpi的設備為準,該設備上1dp = 1px;如果屏幕密度大,1dip代表的px就多,比如在320dpi的屏幕上,1dip=2px(即1dp代表2個像素)。在app開發時,最好用dp來做界面的布局,以保證適配不同屏幕密度的手機。
dp和px的換算公式:
px = dp * (dpi / 160)
我的理解,該公式表示px的數值等于dp的數值*(設備dpi/160)
注意,px、dp是單位,但density沒單位。
dp與px的換算代碼實現
/** * 根據手機的分辨率從 dp 的單位 轉成為 px(像素) */
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f*(dip>=0?1:-1)););
}
/** * 根據手機的分辨率從 px(像素) 的單位 轉成為 dp */
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f*(dip>=0?1:-1)););
}
//dp轉px。第二種方案,根據源碼與第一種方案差+-0.5f,不明緣由
public static int dip2px(Context context, float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, context.getResources().getDisplayMetrics());
}
//sp轉px
public static int sp2px(Context context, float spVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
spVal, context.getResources().getDisplayMetrics());
}
getResources().getDisplayMetrics().densityDpi 就是屏幕密度。
getResources().getDisplayMetrics().density 也可以理解為1dip相當于多少個px啦。
applyDimension的源碼如下,可參考:
/**
* Converts an unpacked complex data value holding a dimension to its final floating
* point value. The two parameters <var>unit</var> and <var>value</var>
* are as in {@link #TYPE_DIMENSION}.
*
* @param unit The unit to convert from.
* @param value The value to apply the unit to.
* @param metrics Current display metrics to use in the conversion --
* supplies display density and scaling information.
*
* @return The complex floating point value multiplied by the appropriate
* metrics depending on its unit.
*/
public static float applyDimension(int unit, float value,
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
安卓app圖標設計
android的尺寸眾多,建議使用分辨率為720x1280 的尺寸設計。這個尺寸 720x1280中顯示完美,在 1080x1920 中看起來也比較清晰;切圖后的圖片文件大小也適中,應用的內存消耗也不會過高。
app啟動圖標為48*48dp,對應各dpi設備,圖像資源像素如下:
| mdpi | hdpi | xhdpi | xxhdpi |
| ---:| ---: | ---:| ---:| ---:|
|4848px|7272px|9496px|144px144px|
操作欄圖標為32*32dp,對應各dpi設備,圖像資源像素如下:其中圖形區域尺寸是24*24dp,可參考平時ui切圖會有部分留白。
| mdpi | hdpi | xhdpi | xxhdpi |
| ---:| ---: | ---:| ---:| ---:|
|3232px|4848px|6464px|96px96px|
通知欄圖標為24*24dp,對應各dpi設備,圖標像素如下:
| mdpi | hdpi | xhdpi | xxhdpi |
| ---:| ---: | ---:| ---:| ---:|
|2424px|3636px|4848px|72px72px|
某些場景需要用到小圖標,大小應當是16*16dp,其中圖形區域尺寸12*12dp。
| mdpi | hdpi | xhdpi | xxhdpi |
| ---:| ---: | ---:| ---:| ---:|
|1616px|2424px|3232px|48px48px|