Android多屏幕適配

要點:php

須要注意一下幾個地方:儘可能使用線性佈局/儘可能使用dip和sp,不要使用px/爲不一樣的分辨率提供不一樣的佈局文件和圖片,接下來爲你詳細介紹下,感興趣的你能夠參考下哈,但願能夠幫助到你

1.儘可能使用線性佈局(LinearLayout)和相對佈局(RelativeLayout),不要使用絕對佈局。html

2.儘可能使用dip和sp,不要使用px。 html5

3.爲不一樣的分辨率提供不一樣的佈局文件和圖片。 android

例如:   express

4.在AndroidMainfest.xml中設置多分辨率支持。 app

複製代碼 代碼以下:
<supports-screens   
android:largeScreens="true"    
android:normalScreens="true"   
android:anyDensity="true"    
android:smallScreens="true"  />
 
總結一下:   
 
1)android:anyDensity="true",系統會依據屏幕密度,自動去找對應的文件夾。   
(1)  若是drawable-hdpi,drawable-mdpi,drawable-ldpi三個文件夾中有同一張圖片資源的不一樣密度表示,那麼系統會去加載drawable_mdpi文件夾中的資源
(2) 若是drawable-hpdi中有高密度圖片,其它兩個文件夾中沒有對應圖片資源,那麼系統會去加載drawable-hdpi中的資源。
(3)  若是drawable-hdpi,drawable-mdpi中有圖片資源,drawable-ldpi中沒有對應的圖片資源,那麼系統會加載drawable-mdpi文件夾中的資源
AndroidManifest.xml文件詳解(supports-screens)
 ---------------------------------------------------

語法(SYNTAX):iphone

<supports-screenside

android:resizeable=["true"|"false"]                   佈局

android:smallScreens=["true" | "false"]                  post

android:normalScreens=["true" | "false"]                  

android:largeScreens=["true" | "false"]                  

android:xlargeScreens=["true" | "false"]                  

android:anyDensity=["true" | "false"]

android:requiresSmallestWidthDp="integer" 

android:compatibleWidthLimitDp="integer"                  

android:largestWidthLimitDp="integer"/>

被包含於(CONTAINED IN):

<manifest>

說明(DESCRIPTION):

這個元素用於指定應用程序所支持的屏幕尺寸,並針對比應用程序所支持的屏幕還要大屏幕,啓用屏幕兼容模式。在應用程序中使用這個元素指定應用程序所支持的屏幕尺寸是相當重要的。

若是應用程序調整尺寸屬性來填充整個屏幕,那麼應用程序就要支持這個給定的尺寸。一般對於大多數應用程序,系統能夠很好的完成這種調整工做,而且爲了讓應用程序在比一個手持設備大的屏幕上工做,你不須要作任何額外的工做。可是,針對不一樣的屏幕尺寸,經過提供可選的佈局資源來優化應用程序的UI常常是很重要的。例如,一個運行在手持設備上的Activity佈局,若是想要運行在平板電腦上,就須要修改這個Activity的佈局。

可是,若是爲了適應不一樣的屏幕尺寸而調整了尺寸,但應用程序也不能很好的工做,就可使用<supports-screens>元素的屬性來控制應用程序是否應該發佈給屏幕較小的設備,或者使用系統的屏幕兼容模式,讓UI放大以適應較大屏幕的要求。在沒有針對較大屏幕尺寸的設計,而且普通的尺寸不能達到合適結果時,屏幕的兼容模式會經過模擬普通尺寸的屏幕和中等密度來縮放UI,以便它可以填充整個屏幕,這樣會致使UI模糊,所以針對大屏幕的優化是比較好的。

注意:Android3.2引入了新的屬性:android:requiresSmallestWidthDp、android:compatibleWidthLimitDp和android:largestWidthLimitDp。若是正在開發Android3.2或更高版本的應用程序,應該使用這些屬性來聲明應用程序所支持的屏幕尺寸,而不是基於通常的屏幕尺寸屬性。

有關如何正確的支持不一樣的屏幕尺寸,以便避免給應用程序使用屏幕兼容模式的更多信息,請閱讀「Supporting Multiple Screens」

http://developer.android.com/guide/practices/screens_support.html

屬性(ATTRIBUTES):

android:resizeable

這個屬性用於指示針對不一樣的屏幕尺寸,應用程序是否能夠調整尺寸。默認值是true。若是這個屬性設置了false,在大的屏幕上,系統會在屏幕兼容模式中運行該應用程序。

這個屬性被廢棄了,引入這個屬性主要是爲了幫助應用程序從1.5過渡到1.6。當多屏幕支持被引入時,就不該該在使用它了。

android:smallScreens

這個屬性用於指定應用程序是否支持較小外形的屏幕。一個small類型的屏幕被定義成一個比normal(傳統的HVGA)類型的屏幕還要小的屏幕。外部服務(如Google Play)不會把不支持小屏的應用程序提供給小屏設備,由於不多有可以確保該應用程序在小屏幕的設備上正常工做的平臺。這個屬性的默認值是true。

android:normalScreens

這個屬性用於指示應用程序是否支持普通外形的屏幕。典型的是HVGA中等密度的屏幕,可是WQVGA低密度和WVGA高密度屏幕也被認爲是普通屏幕。這個屬性的默認值是true。

android:largeScreens

這個屬性用於指示應用程序是否支持較大外形的屏幕。一個large類型的屏幕被定義成一個比normal類型的手持設備的屏幕明顯還要大的屏幕,而且爲了讓應用程序可以良好的使用,使用這個屬性時要特別當心,儘管能夠依賴系統來調整尺寸,以便可以填充屏幕。

這個屬性的默認值實際上在某些版本之間是不一樣的,所以最好在任什麼時候候都明確的聲明這個屬性。若是設置爲false,系統會啓用屏幕兼容模式,這時要格外的當心。

android:xlargeScreens

這個屬性用於指示應用程序是否支持超大外形的屏幕。一個xlarge屏幕被定義成一個比large屏幕還要大的屏幕,如平板電腦,爲了可以讓應用程序良好的使用,須要特別當心的使用這個屬性,儘管能夠依賴系統來UI的尺寸來填充屏幕。

android:anyDensity

這個屬性指明應用程序是否包含了可以適用於任何屏幕密度的資源。

對於支持Android1.6(API Level 4)和更高版本的應用程序,這個屬性的默認值是true,而且除非絕對的確認這是應用程序正常工做所必須的,不然不該該把它設置爲false。只是在應用程序直接操做位圖時才須要禁止這個屬性。

android:requiresSmallestWidthDp

這個屬性用於指定smallestWidth的最小需求。smallestWidth是屏幕空間的最短尺寸(以dp爲單位),它必須是對應用程序的UI是有效的。也就是說它是有效的屏幕的兩個維度的尺寸中最短的那個。所以爲了考慮設備跟應用程序的兼容性,設備的smallestWidth的值必需要大於等於這個屬性所設置的值。一般這個屬性值是針對佈局所支持的最小寬度,而不是屏幕當前的方向。

例如,典型的手持設備屏幕smallestWidth是320dp;7英寸的平板電腦的smallestWidth是600dp;10英寸的平板電腦的smallestWidth是720dp。這些值通常都是最小的寬度,由於它們是屏幕可用空間中最短的那個尺寸。

這對這個尺寸值的比較,須要考慮屏幕的裝飾和系統UI部分。例如,若是系統有一些固定的UI元素要顯示,那麼系統聲明的設備的最小寬度(smallestWidth)要比實際的屏幕尺寸要小,由於被系統UI佔用的屏幕像素對於應用的UI是無效的。所以,這個值應該是應用佈局所使用的最小寬度需求,而無論屏幕的當前方向。

若是應用程序可以針對較小屏幕尺寸進行正確的調整(small尺寸或最小寬度是320dp如下的屏幕),那麼就不須要這個屬性。不然就應該使用這個屬性值跟應用程序所使用的最小屏幕寬度限定符的值(sw<N>dp)相匹配。

警告:Android系統不會關注這個屬性,所以它不會影響應用程序在運行時的行爲。相反,它被服務(如Google Play)用於過濾應用程序。可是,當前Google Play不支持用這個屬性來過濾(在Android3.2上),所以若是應用程序不支持小屏幕設備,就應該繼續使用其餘的尺寸屬性。 這個屬性在API Level 13中被引入。

android:compatibleWidthLimitDp

這個屬性容許在設計應用程序時,經過指定最大的「smallest screen width」來啓用屏幕兼容模式,做爲一個用戶可選的功能。若是設備的有效屏幕的最小邊比這個屬性值大,那麼用戶依然可以安裝該應用程序,可是在運行時要使用屏幕兼容模式。默認狀況下,屏幕兼容模式彷佛被禁止的,而且經過會調整佈局的尺寸來填充屏幕,可是在系統欄中會有一個按鈕,讓用戶選擇屏幕兼容模式的打開和關閉。

若是應用程序跟全部的屏幕尺寸都兼容,而且它的佈局可以被正確的調整尺寸,就不須要使用這個屬性。

注意:當前,屏幕兼容模式只能模擬320dp寬度的手持設備屏幕,所以若是android:compatibleWidthLimitDp的值比320大,那麼屏幕兼容模式就不被適用。

這個在API Level 13中被引入。

android:largestWidthLimitDp

這個屬性容許再設計應用程序時,經過指定最大的「smallest screen width」來強制啓用屏幕兼容模式。若是設備有效屏幕的最小邊比這個屬性值大,應用程序就會運行在屏幕兼容模式中,而用戶沒有辦法禁止這種模式。

若是應用程序跟全部的屏幕尺寸都兼容,而且可以被正確的調整尺寸,就不需使用這個屬性。不然首先要考慮使用android:compatibleWidthLimitDp屬性。只有在因大屏幕尺寸調整而致使破壞了應用程序的功能的時候,而且使用屏幕兼容模式是惟一的方法的時候,才應該使用這個屬性。

注意:當前,屏幕兼容模式只能模擬320dp寬度的手持設備屏幕,所以若是android:compatibleWidthLimitDp的值比320大,那麼屏幕兼容模式就不被適用。

這個在API Level 13中被引入。

-----------------------------------------------------------------------------

一、基本概念

屏幕大小(screen size) – 屏幕的實際大小,用屏幕對角線長度來衡量(好比3.4寸,3.8寸)。android把屏幕分爲如下4種:small,normal,large,extra large。 怎麼判斷?

屏幕密度(Screen Density) -  一塊實際的屏幕區域有多少個像素,通常用dpi衡量(每英寸有多少個點)。相比起medium、high屏幕密度的設備,在一塊肯定大小的屏幕區域l密度爲low的屏幕擁有的像素更少。android把屏幕密度分爲4種:low,medium,high,extra high。

如何判斷是ldpi,mdpi,hdpi?

方向(orientation) -  屏幕方向分爲landscape(橫屏)和portrait(豎屏)。

分辨率(Resolution) -  屏幕上的總實際像素數。對屏幕進行適配時,通常不關注它的分辨率,只關注它的屏幕大小和密度。

與密度無關的像素(Density-independent pixel,dp或dip) -  爲了保證你的UI適合不一樣的屏幕密度,建議你採用dp來定義程序UI。 它的計算方法爲:px = dp * (dpi / 160)

sp(scale-independent pixel)

如何分辨一個屏幕是ldpi、mdpi、hdpi的方法,見下圖

計算屏幕密度

二、怎樣適配多種屏幕

 

a.在manifest裏定義你的程序支持的屏幕類型,相應代碼以下: <supports-screens android:resizeable=["true"| "false"] android:smallScreens=["true" | "false"]   //是否支持小屏 android:normalScreens=["true" | "false"]  //是否支持中屏 android:largeScreens=["true" | "false"]   //是否支持大屏 android:xlargeScreens=["true" | "false"]  //是否支持超大屏 android:anyDensity=["true" | "false"]    //是否支持多種不一樣密度的屏幕 android:requiresSmallestWidthDp=」integer」 android:compatibleWidthLimitDp=」integer」 android:largestWidthLimitDp=」integer」/>

b.對不一樣大小的屏幕提供不一樣的layout。

      好比,若是須要對大小爲large的屏幕提供支持,須要在res目錄下新建一個文件夾layout-large/並提供layout。固然,也能夠在res目錄下創建layout-port和layout-land兩個目錄,裏面分別放置豎屏和橫屏兩種佈局文件,以適應對橫屏豎屏自動切換。

c.對不一樣密度的屏幕提供不一樣的圖片。 應儘可能使用點9格式的圖片,如需對密度爲low的屏幕提供合適的圖片,需新建文件夾drawable-ldpi/,並放入合適大小的圖片。相應的,medium對應drawable-mdpi /,high對應drawable-hdpi/,extra high對應drawable-xhdpi/。 圖片大小的肯定:low:medium:high:extra high比例爲3:4:6:8。舉例來講,對於中等密度(medium)的屏幕你的圖片像素大小爲48×48,那麼低密度(low)屏幕的圖片大小應爲36×36,高(high)的爲72×72,extra high爲96×96。

不一樣密度的屏幕對應的圖片比例

三、多屏幕適配的4條黃金原則 a.在layout文件中設置控件尺寸時應採用wrap_content,fill_parent和dp。

       具體來講,設置view的屬性android:layout_width和android:layout_height的值時,wrap_content,fill_parent或dp比pix更好。相應地,爲了使文字大小更好的適應屏幕應該使用sp來定義文字大小。

b.在程序的代碼中不要出現具體的像素值。

爲了使代碼簡單,android內部使用pix爲單位表示控件的尺寸,但這是基於當前屏幕基礎上的。爲了適應多種屏幕,android建議開發者不要使用具體的像素來表示控件尺寸。

c.不要使用AbsoluteLayout(android1.5已廢棄) 。相應地,應使用RelativeLayout。

d.對不一樣的屏幕提供合適大小的圖片。見上面第2部分。

四、須要注意的地方 以上設置適用於android3.2如下的版本。(本人目前開發是在android2.2上,這部分之後再補充)

五、怎樣測試你的程序是否支持多屏幕適配 通常使用AVD Manager建立多個不一樣大小的模擬器,以下圖

六、參考文檔http://developer.android.com/guide/practices/screens_support.html

 

 

Android多屏幕適配 

原創做品,容許轉載,轉載時請務必以超連接形式標明文章 原始出處 、做者信息和本聲明。不然將追究法律責任。 http://mikewang.blog.51cto.com/3826268/865304

問題:

測試時,發現應用在不一樣的顯示器上顯示效果不一樣(部分文本不能顯示徹底),天然想到屏幕適配的問題。

按照思路整理以下:

(一) 幾個概念

1, Screen size 屏幕的尺寸,即對角線長度(單位inch-英寸)

2, Screen density屏幕密度,即單位長度像素點數(pots/inches)

3, Resolution 分辨率,即屏幕的總像素點數(width * height)

4, Density-independent pixel (dp)獨立像素密度。標準是160dip.即1dp對應1個pixel,計算公式如:px = dp * (dpi / 160),屏幕密度越大,1dp對應 的像素點越多。

 

(二) 屏幕的分類(size & density)

1, 以總像素數分,文本的size等都要改,以下圖所示

    每個分類都有其最小分辨率,以下,可根據分辨率劃分種類:

 

2, 以屏幕密度分,提供不一樣的圖片以下圖所示

Note1:匹配以上面兩種爲參考。

Note2:還有專爲水平(landscape)和豎直(portrait)兩種,使用的少,在此不贅述。

 

(三) Android尋找最佳資源原理

1, 排除與設備設置不符合的資源

2, 根據限定詞(qualifier)的優先級,按照順序查找

3, 在限定詞下,是否存在資源路徑

4, 排除不包含在限定詞中的資源路徑

5,  繼續執行不一樣的限定詞查找,直到找到相應的資源

以下圖所示:

 

(四) 項目步驟:

1, manufest中配置

  1. <supports-screens 
  2.        android:anyDensity="true" 
  3.        android:largeScreens="true" 
  4.        android:normalScreens="true" 
  5.        android:smallScreens="true" 
  6.        android:xlargeScreens="true" /> 

2, 新建對應的資源文件夾

A, Layout

例如,我如今有三個顯示器分辨率:

分別爲1280*720,1024*768,1200*690 

根據以上最低分辨率的要求,分爲xlarge和large兩類,新建兩個文件夾,以下:

以下圖所示:

B, Drawable

以下圖所示:

 在drawable中,以mdpi爲標準(即160dpi)。比例保持爲3:4:5:6,以下圖所示:

 

本文出自 「小新專欄」 博客,請務必保留此出處http://mikewang.blog.51cto.com/3826268/865304

 

Android 多屏幕支持

 

 

另一篇

http://blog.csdn.net/zj_133/article/details/7281140

 

多國語言文件夾

http://guojianhui0906.iteye.com/blog/1271827

 

1.術語和概念

術語

說明

備註

Screen size(屏幕尺寸)

指的是手機實際的物理尺寸,好比經常使用的2.8英寸,3.2英寸,3.5英寸,3.7英寸(對角線長度)

摩托羅拉milestone手機是3.7英寸

Aspect Ratio(寬高比率)

指的是實際的物理尺寸寬高比率,分爲long和nolong

Milestone是16:9,屬於long

Resolution(分辨率)

和電腦的分辨率概念同樣,指手機屏幕縱、橫方向像素個數

Milestone是854*480

DPI(dot per inch)

每英寸像素數,如120dpi,160dpi等,假設QVGA(320*240)分辨率的屏幕物理尺寸是(2英寸*1.5英寸),dpi=160 因此dpi = 分辨率的高寬的平方根(對角線)除以物理尺寸高寬的平方根(對角線).

能夠反映屏幕的清晰度,用於縮放UI的

Density(密度)

屏幕裏像素值濃度,resolution/Screen size能夠反映出手機密度,    (dpi/160)

Density-independent pixel (dip)

指的是邏輯密度計算單位,dip和具體像素值的對應公式是pixel/dip=dpi值/160,也就是pixel = dip * (dpi / 160)

Px (Pixel像素:     不一樣設備顯示效果相同。這裏的「相同」是指像素數不會變,好比指定UI長度是100px,那無論分辨率是多少UI長度都是100px。也正是由於如此才形成了UI在小分辨率設備上被放大而失真,在大分辨率上被縮小。

 

2. DPI值計算

好比:計算WVGA(800*480)分辨率,3.7英寸的密度DPI,如圖1所示

               圖1

Diagonal pixel表示對角線的像素值(=),DPI=933/3.7=252

3.手機屏幕的分類

3.1根據手機屏幕密度(DPI)或屏幕尺寸大小分爲如下3類,如圖2所示

                        

                          圖2

3. 2手機屏幕分類和像素密度的對應關係如表1所示:

Low density (120), ldpi

Medium density (160), mdpi

High density (240), hdpi

Small screen

QVGA (240x320)

Normal screen

WQVGA400 (240x400)WQVGA432 (240x432)

HVGA (320x480)

WVGA800 (480x800)WVGA854 (480x854)

Large screen

WVGA800* (480x800)WVGA854* (480x854)

                                      表1

3.3手機尺寸分佈狀況(http://developer.android.com/resources/dashboard/screens.html)如圖3所示,目前主要是以分辨率爲800*480和854*480的手機用戶居多

                                                        圖3

   從以上的屏幕尺寸分佈狀況上看,其實手機只要考慮3-4.5寸之間密度爲1和1.5的手機

4 UI設計

從開發角度講,應用程序會根據3類Android手機屏幕提供3套UI佈局文件,可是相應界面圖標也須要提供3套,如表2所示

Icon Type

Standard Asset Sizes (in Pixels), for Generalized Screen Densities

Low density screen (ldpi)

Medium density screen (mdpi)

High density screen (hdpi)

Launcher

36 x 36 px

48 x 48 px

72 x 72 px

Menu

36 x 36 px

48 x 48 px

72 x 72 px

Status Bar

24 x 24 px

32 x 32 px

48 x 48 px

Tab

24 x 24 px

32 x 32 px

48 x 48 px

Dialog

24 x 24 px

32 x 32 px

48 x 48 px

List View

24 x 24 px

32 x 32 px

48 x 48 px

                                        表2

5 如何作到自適應屏幕大小呢?

1)界面佈局方面

   須要根據物理尺寸的大小準備5套佈局,layout(放一些通用佈局xml文件,好比界面中頂部和底部的佈局,不會隨着屏幕大小變化,相似windos窗口的title bar),layout-small(屏幕尺寸小於3英寸左右的佈局),layout-normal(屏幕尺寸小於4.5英寸左右),layout-large(4英寸-7英寸之間),layout-xlarge(7-10英寸之間)

2)圖片資源方面

  須要根據dpi值準備5套圖片資源,drawable,drawalbe-ldpi,drawable-mdpi,drawable-hdpi,drawable-xhdpi

Android有個自動匹配機制去選擇對應的佈局和圖片資源

 

四種屏幕尺寸分類:: small, normal, large, and xlarge 四種密度分類: ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high) 須要注意的是: xhdpi是從 Android 2.2 (API Level 8)纔開始增長的分類. xlarge是從Android 2.3 (API Level 9)纔開始增長的分類. DPI是「dot per inch」的縮寫,每英寸像素數。

通常狀況下的普通屏幕:ldpi是120,mdpi是160,hdpi是240,xhdpi是320。

 

 

兩種獲取屏幕分辨率信息的方法:

DisplayMetrics metrics = new DisplayMetrics(); Display display = activity.getWindowManager().getDefaultDisplay(); display.getMetrics(metrics); //這裏獲得的像素值是設備獨立像素dp

//DisplayMetrics metrics=activity.getResources().getDisplayMetrics(); 這樣得到的參數信息不正確,不要使用這種方式。 不能使用android.content.res.Resources.getSystem().getDisplayMetrics()。這個獲得的寬和高是空的。 若是須要爲Android pad定製資源文件,則res目錄下的目錄可能爲: drawable drawable-ldpi drawable-mdpi drawable-hdpi drawable-xhdpi drawable-nodpi drawable-nodpi-1024×600 drawable-nodpi-1280×800 drawable-nodpi-800×480 values values-ldpi values-mdpi values-hdpi values-xhdpi values-nodpi values-nodpi-1024×600 values-nodpi-1280×800 values-nodpi-800×480

 

 

源碼庫 » Android » res

路徑:android-4.0.1/packages/SystemUI/res

 

上一級 目 錄

另外

android中獲取屏幕的長於寬,參考了網上有不少代碼,但結果與實際不符,如個人手機是i9000,屏幕大小是480*800px,獲得的結果卻爲320*533

結果很不靠譜,因而本身寫了幾行代碼,親測一下

測試參數:

測試環境: i9000(三星)

物理屏幕:480*800px

density :1.5

測試代碼:

 

Java代碼 
  1. // 獲取屏幕密度(方法1)  
  2. int screenWidth  = getWindowManager().getDefaultDisplay().getWidth();       // 屏幕寬(像素,如:480px)  
  3. int screenHeight = getWindowManager().getDefaultDisplay().getHeight();      // 屏幕高(像素,如:800p)  
  4.   
  5. Log.e(TAG + "  getDefaultDisplay""screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);  
  6.   
  7.   
  8. // 獲取屏幕密度(方法2)  
  9. DisplayMetrics dm = new DisplayMetrics();  
  10. dm = getResources().getDisplayMetrics();  
  11.   
  12. float density  = dm.density;        // 屏幕密度(像素比例:0.75/1.0/1.5/2.0)  
  13. int densityDPI = dm.densityDpi;     // 屏幕密度(每寸像素:120/160/240/320)  
  14. float xdpi = dm.xdpi;             
  15. float ydpi = dm.ydpi;  
  16.   
  17. Log.e(TAG + "  DisplayMetrics""xdpi=" + xdpi + "; ydpi=" + ydpi);  
  18. Log.e(TAG + "  DisplayMetrics""density=" + density + "; densityDPI=" + densityDPI);  
  19.   
  20. screenWidth  = dm.widthPixels;      // 屏幕寬(像素,如:480px)  
  21. screenHeight = dm.heightPixels;     // 屏幕高(像素,如:800px)  
  22.   
  23. Log.e(TAG + "  DisplayMetrics(111)""screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);  
  24.   
  25.   
  26.   
  27. // 獲取屏幕密度(方法3)  
  28. dm = new DisplayMetrics();  
  29. getWindowManager().getDefaultDisplay().getMetrics(dm);  
  30.   
  31. density  = dm.density;      // 屏幕密度(像素比例:0.75/1.0/1.5/2.0)  
  32. densityDPI = dm.densityDpi;     // 屏幕密度(每寸像素:120/160/240/320)  
  33. xdpi = dm.xdpi;           
  34. ydpi = dm.ydpi;  
  35.   
  36. Log.e(TAG + "  DisplayMetrics""xdpi=" + xdpi + "; ydpi=" + ydpi);  
  37. Log.e(TAG + "  DisplayMetrics""density=" + density + "; densityDPI=" + densityDPI);  
  38.   
  39. int screenWidthDip = dm.widthPixels;        // 屏幕寬(dip,如:320dip)  
  40. int screenHeightDip = dm.heightPixels;      // 屏幕寬(dip,如:533dip)  
  41.   
  42. Log.e(TAG + "  DisplayMetrics(222)""screenWidthDip=" + screenWidthDip + "; screenHeightDip=" + screenHeightDip);  
  43.   
  44. screenWidth  = (int)(dm.widthPixels * density + 0.5f);      // 屏幕寬(px,如:480px)  
  45. screenHeight = (int)(dm.heightPixels * density + 0.5f);     // 屏幕高(px,如:800px)  
  46.   
  47. Log.e(TAG + "  DisplayMetrics(222)""screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);  


結果以下:

 

Java代碼 
  1. E/== MyScreenActivity ===================================  getDefaultDisplay( 8509): screenWidth=320; screenHeight=533  
  2. E/== MyScreenActivity ===================================  DisplayMetrics( 8509): xdpi=156.3077; ydpi=157.51938  
  3. E/== MyScreenActivity ===================================  DisplayMetrics( 8509): density=1.0; densityDPI=160  
  4. E/== MyScreenActivity ===================================  DisplayMetrics(111)( 8509): screenWidth=320; screenHeight=533  
  5. E/== MyScreenActivity ===================================  DisplayMetrics( 8509): xdpi=234.46153; ydpi=236.27907  
  6. E/== MyScreenActivity ===================================  DisplayMetrics( 8509): density=1.5; densityDPI=240  
  7. E/== MyScreenActivity ===================================  DisplayMetrics(222)( 8509): screenWidthDip=320; screenHeightDip=533  
  8. E/== MyScreenActivity ===================================  DisplayMetrics(222)( 8509): screenWidth=480; screenHeight=800  

 

 

分析結果:

 

在onDraw()方法中

方法1和2,獲得的結果都一致,均爲320*533,明顯不是測試機i9000的屏幕大小

方法3,將方法1和2獲得的結果,乘以density後,完美的480*800,perfect!

注:density 大於1的狀況下,須要設置targetSdkVersion在4-9之間,例如
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="10" />

 

 

可是,這就說明方法3必定是通用的嗎?

回答是否認的,由於我也在模擬器、HTC G14物理機,以及ViewSonic、Galaxy平板上測試過,方法3在density=1.5時,放大了實際屏幕值,例如:HTC G14

在HTC G14上,實際屏幕大小,直接經過dm.widthPixels、dm.heightPixels便獲得了實際物理屏幕大小(540,960)

致使沒法經過一種通用的方法獲取真實物理屏幕大小的緣由,可能就是由於Android系統開源,不一樣的手機生產廠商沒有統一的製造標準,來規定手機屏幕。

 

仔細分析代碼,發現問題出在代碼:

getWindowManager().getDefaultDisplay().getMetrics(dm)

Initialize a DisplayMetrics object from this display's data.

 

dm = getResources().getDisplayMetrics()

Return the current display metrics that are in effect for this resource object. The returned object should be treated as read-only.

 

 

手機尺寸分佈狀況(http://developer.android.com/resources/dashboard/screens.html)如圖所示,

目前主要是以分辨率爲800*480和854*480的手機用戶居多 從以上的屏幕尺寸分佈狀況上看,其實手機只要考慮3-4.5寸之間密度爲1和1.5的手機

 

二、android多屏幕支持機制 Android的支持多屏幕機制即用爲當前設備屏幕提供一種合適的方式來共同管理並解析應用資源。 Android平臺中支持一系列你所提供的指定大小(size-specific),指定密度(density-specific)的合適資源。 指定大小(size-specific)的合適資源是指small, normal, large, and xlarge。 指定密度(density-specific)的合適資源,是指ldpi (low), mdpi (medium), hdpi(high), and xhdpi (extra high). Android有個自動匹配機制去選擇對應的佈局和圖片資源 1)界面佈局方面    根據物理尺寸的大小準備5套佈局:    layout(放一些通用佈局xml文件,好比界面頂部和底部的佈局,不會隨着屏幕大小變化,相似windos窗口的titlebar),    layout-small(屏幕尺寸小於3英寸左右的佈局),      layout-normal(屏幕尺寸小於4.5英寸左右),    layout-large(4英寸-7英寸之間),    layout-xlarge(7-10英寸之間) 2)圖片資源方面   須要根據dpi值準備5套圖片資源:    drawable:主要放置xml配置文件或者對分辨率要求較低的圖片    drawalbe-ldpi:低分辨率的圖片,如QVGA (240x320)    drawable-mdpi:中等分辨率的圖片,如HVGA (320x480)    drawable-hdpi:高分辨率的圖片,如WVGA (480x800),FWVGA (480x854)    drawable-xhdpi:至少960dp x 720dp

Android有個自動匹配機制去選擇對應的佈局和圖片資源。   系統會根據機器的分辨率來分別到這幾個文件夾裏面去找對應的圖片。   在開發程序時爲了兼容不一樣平臺不一樣屏幕,建議各自文件夾根據需求均存放不一樣版本圖片。

 

三、AndroidManifest.xml 配置

ndroid從1.6和更高,Google爲了方便開發者對於各類分辨率機型的移植而增長了自動適配的功能\android:largeScreens="true"\android:normalScreens="true"\android:smallScreens="true"\android:anyDensity="true"/>

3.1是否支持多種不一樣密度的屏幕 android:anyDensity=["true" | "false"]  若是android:anyDensity="true" 指應用程序支持不一樣密度,會根據屏幕的分辨率自動去匹配。 若是android:anyDensity="false" 應用程序支持不一樣密度,系統自動縮放圖片尺寸和這個圖片的座標。具體解釋一下系統是如何自動縮放資源的。 例如咱們在hdpi,mdpi,ldpi文件夾下擁有同一種資源,那麼應用也不會自動地去相應文件夾下尋找資源,這種狀況都是出如今高密度,以及低密度的手機上,好比說一部240×320像素的手機, 若是設置android:anyDensity="false",Android系統會將240 x 320(低密度)轉換爲320×480(中密度),這樣的話,應用就會在小密度手機上加載mdpi文件中的資源。

3.2是否支持大屏幕 android:largeScreens=["true" | "false"] 若是在聲明不支持的大屏幕,而這個屏幕尺寸是larger的話,系統使用尺寸爲("normal")和密度爲("medium)顯示, 不過會出現一層黑色的背景。

3.3是否支持小屏幕 android:smallScreens=["true" | "false"] 若是在聲明不支持的小屏幕,而當前屏幕尺寸是smaller的話,系統也使用尺寸爲("normal")和密度爲("medium)顯示 若是應用程序能在小屏幕上正確縮放(最低是small尺寸或最小寬度320dp),那就不須要用到本屬性。不然,就應該爲最小屏幕寬度標識符設置本屬性 來匹配應用程序所需的最小尺寸。

 

四、Android提供3種方式處理屏幕自適應

4.1預縮放的資源(基於尺寸和密度去尋找圖片)

1)若是找到相應的尺寸和密度,則利用這些圖片進行無縮放顯示。

2)若是無法找到相應的尺寸,而找到密度,則認爲該圖片尺寸爲 "medium",利用縮放顯示這個圖片。

3)若是都沒法匹配,則使用默認圖片進行縮放顯示。默認圖片默認標配 "medium" (160)。

4.2自動縮放的像素尺寸和座標(密度兼容)

1)若是應用程序不支持不一樣密度android:anyDensity="false",系統自動縮放圖片尺寸和這個圖片的座標。

2)對於預縮放的資源,當android:anyDensity="false",也不生效。

3)android:anyDensity="false",只對密度兼容起做用,尺寸兼容沒效果

4.3兼容更大的屏幕和尺寸(尺寸兼容)

1)對於你在聲明不支持的大屏幕,而這個屏幕尺寸是normal的話,系統使用尺寸爲   ("normal")和密度爲("medium)顯示。

2.)對於你在聲明不支持的大屏幕,而這個屏幕尺寸是larger的話,系統一樣使用尺寸爲("normal")和密度爲("medium)顯示, 不過會出現一層黑色的背景。

 

五、Android系統自動適配技巧 Android系統採用下面兩種方法來實現應用的自動適配: 1)佈局文件中定義長度的時候,最好使用wrap_content,fill_parent, 或者dp進行描述,這樣能夠保證在屏幕上面展現的時候有合適的大小 2)爲不一樣屏幕密度的手機,提供不一樣的位圖資源,可使得界面清晰無縮放。 對應bitmap資源來講,自動的縮放有時會形成放大縮小後的圖像變得模糊不清,這是就須要應用爲不一樣屏幕密度配置提供不一樣的資源:爲高密度的屏幕提供高清晰度的圖像等。 3)不要使用AbsoluteLayout 4)像素單位都使用DIP,文本單位使用SP

 

六、在代碼中獲取屏幕像素、屏幕密度 DisplayMetrics metric = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metric); int width = metric.widthPixels;  // 屏幕寬度(像素) int height = metric.heightPixels;  //屏幕高度(像素) float density = metric.density;  // 屏幕密度(0.75 /1.0 / 1.5) int densityDpi = metric.densityDpi;  //屏幕密度DPI(120 / 160 / 240)

 

七、 通常多分辨率處理方法及其缺點 7.1 圖片縮放 基於當前屏幕的精度,平臺自動加載任何未經縮放的限定尺寸和精度的圖片。若是圖片不匹配,平臺會加載默認資源而且在放大或者縮小以後能夠知足當前界面的顯示要求。例如,當前爲高精度屏幕,平臺會加載高精度資源(如HelloAndroid中drawable-hdpi中的位圖資源),若是沒有,平臺會將中精度資源縮放至高精度,致使圖片顯示不清晰。 7.2 自動定義像素尺寸和位置 若是程序不支持多種精度屏幕,平臺會自動定義像素絕對位置和尺寸值等,這樣就能保證元素能和精度160的屏幕上同樣能顯示出一樣尺寸的效果。例如,要讓WVGA 高精度屏幕和傳統的HVGA屏幕同樣顯示一樣尺寸的圖片,當程序不支持時,系統會對程序慌稱屏幕分辨率爲320×480,在(10,10)到(100,100)的區域內繪製圖形完成以後,系統會將圖形放大到(15,15)到(150,150)的屏幕顯示區域。 7.3 兼容更大尺寸的屏幕 當前屏幕超過程序所支持屏幕的上限時,定義supportsscreens元素,這樣超出顯示的基準線時,平臺在此顯示黑色的背景圖。例如,WVGA中精度屏幕上,如程序不支持這樣的大屏幕,系統會謊稱是一個320×480 的,多餘的顯示區域會被填充成黑色。 7.4 採用OpenGL 動態繪製圖片 Android 底層提供了OpenGL的接口和方法,能夠動態繪製圖片,可是這種方式對不熟悉計算機圖形學的開發者來說是一個很大的挑戰。通常開發遊戲,採用OpenGL方式。 7.5 多個apk 文件 Symbian 和傳統的J2ME就是採用這種方式,爲一款應用提供多個分辨率版本,用戶根據本身的需求下載安裝相應的可執行文件。針對每一種屏幕單獨開發應用程序不失爲一種好方法,可是目前GoogleMarket 對一個應用程序多個分辨率版本的支持還不完善,開發者仍是須要儘量使用一個apk 文件適應多個分辨率。

本文歡迎轉載,但請註明做者與出處:

做者:流星

出處:http://blog.sina.com.cn/staratsky

Android的支持多屏幕的原理是一套內置的兼容性特徵,即用爲當前設備屏幕提供一種合適的方式來共同管理並解析應用資源。雖然android平臺負責大部分解析應用的工做,可是也爲開發者提供瞭如何控制應用呈現的兩個關鍵方法,它們的使用方法以下:

      Android平臺中支持一系列你所提供的指定大小(size-specific),指定密度(density-specific)的合適資源。指定大小(size-specific)的合適資源是指smallnormallarge, and xlarge。指定密度(density-specific)的合適資源,是指ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high).

      Android平臺還提供 <supports-screens> manifest文件節點元素,它的屬性包括: android:smallScreens

android:normalScreensandroid:largeScreens, and android:xlargeScreens.它能夠用來指定應用程序支持哪些尺寸屏幕。<supports-screens>節點另一個屬性android:anyDensity能夠用來指定應用程序是否支持內置支持多密度屏幕的機制。

 

      在應用程序運行的時候,android平臺將提供三種方式支持應用程序,以確保應用程序以儘量好的效果呈如今當前設備屏幕上,這三種具體方式以下:

      一、預前縮放(pro-scaling)資源(如圖片)

           基於當前屏幕的密度,android平臺會從應用程序自動加載指定大小,與密度的資源(均未縮放),若是沒有適配的資源可用,平臺將加載默認文件夾下的資源(即drawable文件夾中的資源)並根據須要縮小或放大資源以適配當前屏幕的通常屏幕密度。除非資源被加載到指定密度目錄下,通常狀況平臺加載的默認資源是展示效果最好的,展示在基於最基本密度爲"medium" (160)的屏幕上。

           例如:若是當前屏幕的密度爲高密度(high),平臺將加載drawable-hdpi文件夾下的資源,使用時並不縮放圖片大小。若是drawable-hdpi中無資源可用,或無此文件夾,平臺將加載默認資源即drawable文件裏的資源,而且放大圖片大小,從基本密度到最大密度。

      二、自動縮放像素維值與座標

           若是應用程序不支持多屏幕,平臺將自動縮聽任何絕對像素座標,像素維值,像素數學。平臺如此作是爲確保像素定義的屏幕元素更接近屏幕物理尺寸呈現,像它們在最基本密度160上表現的同樣。平臺對於應用程序的縮放很明顯,而且會認爲應用程序屏幕大小爲縮放後的像素維值而不是物理像素維值

           例如:假定用一個WVGA的高密度屏幕,480*800,至關於傳統HVGA的屏幕大小,可是運行一個不支持多屏幕的應用程序。在這種狀況下,系統在獲取屏幕大小時,會誤認爲是320*533。而後,會使從座標(10,10)到座標(100,100)的長方形失效,系統將自動縮放座標到合適大小,即從(15,15)到(150,150)。這種狀況也會發生在其它地方,若是應用程序運行在低密度的屏幕上,座標也會被縮小

      三、在大屏幕上的兼容模式

 

1.Screen size 屏幕實際尺寸。 Android講屏幕實際尺寸分爲3個通用的尺寸。       2.Aspect ratio 長寬比
   3.Resolution 分辨率
   4.Density 密度
   5.Density-independent pixel 密度無關的像素
介紹:Adnroid1.6或以上SDK,在AndroidManifest.xml中提供新的一個元素<supports-screens>用於支持多屏幕機制。 <supports-screens          android:largeScreens="true"   是否支持大屏           android:normalScreens="true"  是否支持中屏           android:smallScreens="true"   是否支持小屏           android:anyDensity="true"     是否支持多種不一樣密度 />
Android提供3種方式處理屏幕自適應 一.預縮放的資源(基於尺寸和密度去尋找圖片) 1.若是找到相應的尺寸和密度,則利用這些圖片進行無縮放小時。 2.若是無法找到相應的尺寸,而找到密度,則認爲該圖片尺寸爲 "medium",利用縮放這個圖片顯示。 3.若是都沒法匹配,則使用默認圖片進行縮放顯示。默認圖片默認標配 "medium" (160)。
二.自動縮放的像素尺寸和座標(密度兼容) 1.若是應用程序不支持不一樣密度android:anyDensity="false",系統自動縮放圖片尺寸和這個圖片的座標。  (代碼中體現) 2.對於預縮放的資源,當android:anyDensity="false",也不生效。 3.android:anyDensity="false",只對密度兼容起做用,尺寸兼容沒效果
三.兼容模式顯示在大屏幕,尺寸(尺寸兼容) 1.對於你在<supports-screens>聲明不支持的大屏幕,而這個屏幕尺寸是normal的話,系統使用尺寸爲   ("normal")和密度爲("medium)顯示。 2.對於你在<supports-screens>聲明不支持的大屏幕,而這個屏幕尺寸是larger的話,系統一樣使用尺寸爲                   ("normal")和密度爲("medium)顯示,不過會出現一層黑色的背景。不是居中顯示。
密度獨立: 系統默認應用支持DIP單位的,三個使用DIP的地方: 1.加載資源時,使用DIP實現預縮放的資源。 2.在Layout使用DIP,系統自動完成縮放。 3.在應用程序中,自動縮放一些絕對像素。    (只有在android:anyDensity="false"生效)即屏幕自適應方式二 4.像素單位都使用DIP,文本單位使用SP
最佳屏幕獨立實踐: 1.使用wrap_content, fill_parent 和使用dip做爲像素單位in XML layout files。 2.避免使用AbsoluteLayout 3.在代碼中,不要使用像素數字硬編碼,而是要經過dip轉換爲px。     例子:   你使用手勢分析器分析一個scroll手勢,假如,你滾動的距離是16px。 1.在一個160dip的屏幕中,你實際移動距離 16px / 160dpi = 1/10th of an inch (or 2.5 mm) 2.在一個240dip的屏幕中,你實際移動距離 16px / 240dpi = 1/15th of an inch (or 1.7 mm)  // The gesture threshold expressed in dip  private static final float GESTURE_THRESHOLD_DIP = 16.0f;   // Convert the dips to pixels   final float scale = getContext().getResources().getDisplayMetrics().density;   mGestureThreshold = (int) (GESTURE_THRESHOLD_DIP * scale); 4.使用密度和/或尺寸特定資源(經過文件夾)
關於預縮放或者自動縮放圖片或9格圖1.系統是必定對會資源包下的圖片進行合理的縮放。   例如:一張240x240高密度圖片,顯示在中密度的屏幕上,圖片大小自動變爲160x160。2.你在API中不會獲得被縮放後的圖片尺寸,獲得仍是你原來圖片的尺寸。3.若是你不想系統自動幫你縮放圖片,能夠創建一個res/drawable-nodpi文件夾,存放你的圖片。4.也能夠經過BitmapFactory.Options 完成系統自動縮放圖片或9格圖(在畫圖時)。

5.自動縮放圖片比預縮放花費更多CPU,可是用更少內存(RAM or ROM ?)

 

 

Android : dip/dppx(pixel)之間的相互轉換

Author : Aoyousatuo Zhao

http://blog.sina.com.cn/aoyousatuo

 

在Android應用的開發過程當中,咱們經常須要給組件佈局定位。這就涉及到Android經常使用的兩個計量單位dip/dp, px.下面筆者就這兩個單位作一個簡要的介紹。

dip或者dp是device independent pixels(設備獨立像素)的縮寫。這個單位提出的目的主要是爲了讓應用的UI佈局適應各類分辨率的顯示設備。Android會將dp最終轉換成具體顯示設備的像素數,這樣就提升了程序的可移植性。

px是pixel的縮寫,它表示一個實實在在的物理像素。這個單位使用起來比較方便,可是組件一旦定位就固定了,它不會隨着設備的分辨率不一樣而改變,使用該單位的程序可移植性較差。

舉個例子,在400像素寬的屏幕上從第0個像素到第399個像素畫一條橫線,咱們能夠看到這條線橫向貫穿了整個屏幕,而後咱們將相同的畫線程序運行在800像素寬的屏幕上,則咱們只能看到這條線只有屏幕的一半。若是換做dp爲單位,則在這兩種分辨率的屏幕上的線基本都橫向貫通。

因此在開發中,爲了提升程序對各類設備的適應性,咱們最好使用dp或者dip爲單位。知道了這兩個單位的特色,問題就來了。咱們發現雖然一些組件能夠在佈局文件中經過dip或者dp單位來定構。可是,組件類的相關方法卻只能以像素爲單位。例如,設置GridView組件類的列間距。這種狀況下就涉及到了dip/dp與px之間的相互轉換。筆者直接給出兩個方法你們就清楚了,請看:

 

public int dip2px(Context context, floatdipValue)

{

floatm=context.getResources().getDisplayMetrics().density ;

return (int)(dipValue * m + 0.5f) ;

}

 

public int px2dip(Context context, floatpxValue)

{

  float m=context.getResources().getDisplayMetrics().density;

  return (int)(pxValue / m + 0.5f) ;

}

 

面對Android設備那混亂的硬件體系,最淡定的開發者也會難免蛋疼起來。在作Android UI的時候,考慮最多的就是這些不一樣設備的適配問題。在爲不一樣分辨率設計不一樣UI的時候,咱們首先要知道目標設備的分辨率究竟是多少。如何計算出來?

水果手機常常喜歡用分辨率超過人眼極限來標榜本身的設備有多麼牛B,聽說iPhone 4S的分辨率達到了326 PPI(pixel per inch),這個數值的計算公式爲:

開方(屏幕寬度平方+屏幕高度平方)÷對角線尺寸

iPhone 4S,960×640像素,對角線尺寸3.5英寸,用上面的公式計算結果以下:

sqrt(sqr(960) + sqr(640)) / 3.5 ≈ 329.65

看來水果公司並未說謊。只是3.5寸的屏搞這麼高的分辨率,考視力麼?

和水果比起來,Android就更加複雜了,它把屏幕分紅small,normal,large,xlarge四種,其對應的屏幕尺寸以下:

  • xlarge 至少960dp x 720dp
  • large 至少640dp x 480dp
  • normal 至少470dp x 320dp
  • small 至少426dp x 320dp

dp(Density-independent pixel)是一個密度無關的像素單位,是用來表示基於160 dpi的設備計算出來的虛擬像素。

屏幕分辨率被分紅low dpi,medium dpi,high dpi,extra high dpi。詳見下圖:

Android設備尺寸定義

最近的Android設備屏幕分佈圖:

Android設備尺寸分佈

相關文章
相關標籤/搜索