編輯:關於Android編程
如果想在不同型號手機對同一個應用做適配,如果你在xml中全部使用dp沒有使用px,那麼適配上依然很有可能出問題!
無數人存在誤區,認為自己使用的都是dp,為什麼在手機A上面和手機B上面看上去比例不一樣,為什麼在A手機上顯示正好而手機B上卻顯示到屏幕外面
每次解釋的都很累,所以寫此blog
首先先明確幾個概念
density值表示每英寸有多少個顯示點(*)
dip/dp: device independent pixels(設備獨立像素)
注意:dip與屏幕密度有關,屏幕密度與硬件有關,硬件設置不正確,有可能導致dip不能正常顯示。在屏幕密度為160的顯示屏上,1dip=1px
下面是一些分辨率信息
名稱 分辨率 屏幕密度
QVGA 320*240 120
WQVGA400 400*240 120
WQVGA432 432*240 120
HVGA 640*480 160
WSVGA 1024*600 160
WXGA800 1280*800 160
WVGA800 800*480 240
WVGA854 854*480 240
WXGA720 1280*720 320
下面沒有特殊說明的話,屏幕的寬度都指其像素數
我們在手機A上面放了一張圖片,120px寬,手機屏幕240px寬,也就是說圖片的寬度占了整個屏幕的一半
如果把應用安裝在手機B上,B的寬度=320px,那麼我們希望圖片寬度為多少呢?如果大家希望按著比例縮放,那圖片寬度應該是160px,占屏幕寬度的50%
如果我們在xml中使用的單位為dp,下面看看如何保持這個比例:
px = (density/160)dp(density這裡是(*)的意思)
我們把所期待的比例記為rate,baseDensity=160,屏幕的寬度(像素數)為x,屏幕密度為density
那麼rate=((density/baseDensity)*dp)/x;
這裡baseDensity是已知的=160,dp也是已知的,因為是你寫的嘛。
未知的是density屏幕密度和屏幕寬度x
rate可以寫為:
rate=(dp/baseDensity)*(density/x);
現在情況就比較明朗了,rate=K(常數)*(density/x);
如果想保持rate不變,那麼需要保證density/x保持比例
給數學不好的同學多解釋兩句
想保持rate的話,必須要手機A的屏幕密度/屏幕寬度=手機B的屏幕密度/屏幕寬度
或者說手機A的屏幕密度/手機B的屏幕密度=手機A的屏幕寬度/手機B的屏幕寬度
同樣,如果你要保持縱向也保持等比縮放,那麼也同樣需要保持比例。
只有這樣,你的應用才能看上去是等比縮放的。
使用dp保持比例只和這些有關,和你屏幕大小半點關系都沒有。
還有另一種方式來保持比例:就是直接使用比例方式定義組件大小
但是很有局限性,只有LinearLayout中可以使用android:layout_weight屬性
其實很容易理解,給大家舉個例子
很多人覺得,如果項目中全部使用dp,那麼就可以完美移植。
我們的一個移植項目,任務是把應用從A(分辨率為WXGA720=1280*720)移植到B(分辨率WVGA800=800*480)
其中A的密度=320,B的密度為240
我們現在來看看A橫向有多少個dp
A dp數=720/(320/160)=360
B dp數=480/(240/160)=320
手機A橫向有360個dp,如果你的圖片占用360個dp,B去哪找你多出來的40dp呢!必然它會顯示在屏幕外面阿!
ps:下面是一點相關內容
下面是函數void android.util.DisplayMetrics.setToDefaults()
[java]
public void setToDefaults() {
widthPixels = 0;
heightPixels = 0;
density = DENSITY_DEVICE / (float) DENSITY_DEFAULT;
densityDpi = DENSITY_DEVICE;
scaledDensity = density;
xdpi = DENSITY_DEVICE;
ydpi = DENSITY_DEVICE;
noncompatWidthPixels = 0;
noncompatHeightPixels = 0;
}
其中density變量注釋如下
density變量注釋 寫道
float android.util.DisplayMetrics.density
The logical density of the display.
This is a scaling factor for the Density Independent Pixel unit, where one DIP is one pixel on an approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), providing the baseline of the system's display.
Thus on a 160dpi screen this density value will be 1; on a 120 dpi screen it would be .75; etc.
This value does not exactly follow the real screen size (as given by xdpi and ydpi, but rather is used to scale the size of the overall UI in steps based on gross changes in the display dpi.
For example, a 240x320 screen will have a density of 1 even if its width is 1.8", 1.3", etc.
However, if the screen resolution is increased to 320x480 but the screen size remained 1.5"x2" then the density would be increased (probably to 1.5).
See Also:
DENSITY_DEFAULT
可以看出這個density是個近似值,並不嚴格按著真實屏幕尺寸計算。
在Android上開發一些小應用既可以積累知識又可以增加樂趣,與任務式開發不同,所以想到在And
主要內容1. Call涉及的目錄結構及框架結構2. InCallUI層的基本架構(所涉及的Presenter、Fragment及Activity)3. Call的幾種狀態
Android基礎入門教程——10.7 WindowManager(窗口管理服務)標簽(空格分隔): Android基礎入門教程本節引言: 本節給
本文實例講述了Android編程重寫ViewGroup實現卡片布局的方法。分享給大家供大家參考,具體如下:實現效果如圖:實現思路1. 重寫onMeasure(int wi