新聞中心
要想使自己的布局在不同設(shè)備達(dá)到精準(zhǔn)空置,理清理順Android布局長度單位之間關(guān)系很有必要,否則你也許會經(jīng)常撓頭為什么顯示出來的布局不是自己定義的效果呢,有些東西,雖然基礎(chǔ),但是弄個透徹也需要花些功夫,廢話不多說,下面開始。

成都創(chuàng)新互聯(lián)公司長期為成百上千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為赤峰企業(yè)提供專業(yè)的成都做網(wǎng)站、成都網(wǎng)站制作,赤峰網(wǎng)站改版等技術(shù)服務(wù)。擁有10年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
1.先了解一下Android有支持哪些長度單位:
px: pixels(像素). 不同設(shè)備顯示效果相同,比如我們800*480的屏幕寬度就是 800px
dip: device independent pixels(設(shè)備獨立像素). 不同設(shè)備有不同的顯示效果,這個和設(shè)備硬件有關(guān),通常屏幕大時,density就大,屏幕小時,density就小
屏幕實際分辨率為240px*400px時,densitydpi=120
屏幕實際分辨率為320px*533px,densityDpi=160
屏幕實際分辨率為480px*800px,densityDpi=240
而dip與px之間的換算關(guān)系是:
pixs =dips * (densityDpi/160),也就是說當(dāng)densityDpi=160時,1dip=1px
sp: scaled pixels(放大像素),sp的大小取決于系統(tǒng)metrics.scaledDensity值大小
pt: point,是一個標(biāo)準(zhǔn)的長度單位,1pt=1/72英寸,用于印刷業(yè)(基本用不到)
pt與px的換算關(guān)系:pixs = pt*xdpi * (1.0f/72);xdpi表示1英寸像素個數(shù)
in(英寸)長度單位(基本用不到)
in與px的換算關(guān)系:pixs = in*xdpi
mm(毫米)長度單位(基本用不到)
mm與px的換算關(guān)系:pixs = mm * xdpi * (1.0f/25.4f)
2.系統(tǒng)獲取長度單位
看了上面具體長度單位的含義你會產(chǎn)生一個疑問,不同單位換算取決于系統(tǒng)的一些屬性,比如densityDpi的值,xdpi的值,那么系統(tǒng)這些值在哪里獲取了,直接看測試用例:
- public void testgetdisplay(){
- WindowManager wm = (WindowManager) this.getInstrumentation().getContext().getSystemService(Context.WINDOW_SERVICE);
- DisplayMetrics mDisplayMetrics = new DisplayMetrics();
- wm.getDefaultDisplay().getMetrics(mDisplayMetrics);
- System.out.println("display.height="+wm.getDefaultDisplay().getHeight());
- System.out.println("display.width="+wm.getDefaultDisplay().getWidth());
- System.out.println("densityDpi="+mDisplayMetrics.densityDpi);
- System.out.println("xdpi="+mDisplayMetrics.xdpi);
- System.out.println("density="+mDisplayMetrics.density);
- }
3.densityDpi與drawable-(hdpi,mdpi,ldpi)之間的關(guān)系
系統(tǒng)drawable有hdpi,mdpi,ldpi三個文件夾下面存放不同尺寸的圖片,使用哪個文件下的文件,與系統(tǒng)densityDpi值是有關(guān)系的。
densityDpi=120:ldpi densityDpi=160:mdpi densityDpi=240:hdpi
前面我又說過densityDpi取決于顯示屏,這樣你就了解了為什么不同顯示屏WVGA,HVGA,QVGA會采用不同drawable-(hdpi,mdpi,ldpi)圖片。
分辨率為240px*400px,densityDpi=120-->QVGA:ldpi
分辨率為320px*533px,densityDpi=160 -->HVGA:mdpi
分辨率為480px*800px,densityDpi=240 -->WVGA:WVGA
4.深入了解代碼
盡管了解上面這些理論值,但是有時候發(fā)現(xiàn)設(shè)置了不同長度單位,可顯示出來的效果卻出人預(yù)想,我曾經(jīng)就碰到過這種撓頭的問題,為解決這個問題,只有深入代碼,一探究竟了。
在深入代碼前我們首先要搞清楚一個問題,那就是代碼中所有長度值的單位都是px,手上沒有現(xiàn)成的例子就以現(xiàn)在我研究的/Launcher2/res/layout-land/workspace_screen.xml為例,看一個自定義屬性:
launcher:cellWidth="105pt"
該屬性自定義了一個桌面快捷圖標(biāo)的寬度,若讀者自己測試,自己寫個測試view,設(shè)置屬性:
android:layout_width="800px"
是一樣的。
當(dāng)view被創(chuàng)建的時候,xml中的屬性值存在參數(shù)AttributeSet attrs中:
- public CellLayout(Context context, AttributeSet attrs, int defStyle)
繼續(xù)看該構(gòu)造函數(shù)的實現(xiàn)代碼:
- public CellLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- //獲取自定義屬性組CellLayout中的所有自定義屬性,關(guān)于自定義屬性,這里不作展開說明
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0);
- //獲取屬性cellWidth的值,長度單位將轉(zhuǎn)換為px
- mCellWidth = a.getDimensionPixelSize(R.styleable.CellLayout_cellWidth, 10);
- 。。。
- }
實現(xiàn)長度單位換算的關(guān)鍵代碼就在a.getDimensionPixelSize(R.styleable.CellLayout_cellWidth, 10),直接深入到關(guān)鍵代碼:
- public int getDimensionPixelSize(int index, int defValue)
- public static int complexToDimensionPixelSize(int data,DisplayMetrics metrics)
- 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;
- }
unit就是指單位類型,這個怎么來的我沒有,但我想它肯定是在解析xml是根據(jù)不同單位轉(zhuǎn)換的。
本文名稱:Android布局中長度單位的深入研究
轉(zhuǎn)載注明:http://www.dlmjj.cn/article/cdgioie.html


咨詢
建站咨詢
