Android開發中的density

ComptibilityInfo.javahtml

 

http://www.tuicool.com/articles/ZZZRNfjava

 

andorid界面單位開發是應該是dipandroid

自適應,包括元素大小自適應,和位置自適應。     web

元素大小:           express

圖片默認會自適應的。瀏覽器

dip會自適應。佈局

自適應問題。一個公式 px=dip*(density/160);(density/160)在android系統中對應 DisplayMetrics.density在一固定的手機上它是一個常數,0.75,1,1.5。等。有了這個常數用dip作單位在不一樣手機上就有不一樣的px了。這就是縮放原理。           ui

drawable-hdpi、drawable-mdpi、drawable-ldpi中的圖片是自動選擇的。可是若是對應的文件夾下沒有所需的圖片它會在其餘兩個文件夾下尋找,找到了按density縮放。           編碼

元素座標:           spa

圖片座標,和觸屏事件座標。 都用相對座標                  

 

 

自適應原則:圖片縮放自適應,位置用相對位置(單位也用dip)。

全部的機型寬都是相等的dip數,高不必定是相等的dip數。

 

240x320 density=120 320dipx426.6dip

320x480 density=160 320dipx480dip

480x800 density=240 320dipx533.3dip

480x854 density=240 320dipx569.33dip

 

        我感受,作手機的屏幕自適應比作web的瀏覽器兼容更麻煩..如下是搜到的資料,原來android還有這些鮮爲人知的東西:               一:不一樣的layout                 Android手機屏幕大小不一,有480x320, 640x360, 800x480.怎樣才能讓App自動適應不一樣的屏幕呢?                     其實很簡單,只須要在res目錄下建立不一樣的layout文件夾,好比layout-640x360,layout-800x480,全部的layout文件在編譯以後都會寫入R.java裏,而系統會根據屏幕的大小本身選擇合適的layout進行使用。                 二:hdpi、mdpi、ldpi         在以前的版本中,只有一個drawable,而2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三個,這三個主要是爲了支持多分辨率。         drawable- hdpi、drawable- mdpi、drawable-ldpi的區別:         (1)drawable-hdpi裏面存放高分辨率的圖片,如WVGA (480x800),FWVGA (480x854)                 (2)drawable-mdpi裏面存放中等分辨率的圖片,如HVGA (320x480)                 (3)drawable-ldpi裏面存放低分辨率的圖片,如QVGA (240x320)         系統會根據機器的分辨率來分別到這幾個文件夾裏面去找對應的圖片。                 在開發程序時爲了兼容不一樣平臺不一樣屏幕,建議各自文件夾根據需求均存放不一樣版本圖片。           

 

 

 

      

 

    

 

 

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

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

Density(密度)

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

 

Density-independent pixel (dip)

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

 

 

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有個自動匹配機制去選擇對應的佈局和圖片資源

 

今天一個開發者問到我爲何遊戲開發要刪除項目下的hdpi、mdpi和ldpi文件夾;下面詳細給你們解答一下:

         首先童鞋們若是看過我寫的《       【Android遊戲開發二十一】Android os設備謊話分辨率的解決方案!      》這一節的話都應該知道Android從1.6和更高,Google爲了方便開發者對於各類分辨率機型的移植而增長了自動適配的功能;    

        自動適配的原理很簡單,只要你創建的項目是1.6或者更高都會看到項目下有drawable-hdpi、drawable-mdpi、drawable-ldpi 三個文件夾,這三個文件夾分別放置高清分辨率、中分辨率、低分辨率的資源文件;那麼若是你的項目在高清分辨率上運行的話,系統會默認索引drawable-hdpi文件夾下的資源,其餘雷同;

         那麼既然系統會自動找匹配的文件夾,那麼確定會出現找不到的狀況,好比當前你的應用在高清分辨率運行,假設代碼中加載一張「himi.png」的圖,那麼系統首先會去drawable-hdpi文件夾下去找這張圖,一旦找不到,系統會再到其餘drawable下尋找,再假設你其實把這張「himi.png」放在了drawable-mdpi中,那麼系統會默認把這張圖片放大;反之同樣,若是你在低分辨率中運行加載一張圖片的話,一旦你將圖片放入高清的drawable-dpi中,那麼系統默認縮小這張圖;

        總結來講:若是你的應用想適配高、中、低分辨率,那麼你須要有3套圖放入對應的文件夾中,這樣系統會智能加載;若是你就想保留一個文件夾,不想讓系統智能尋找縮放的話,有兩種方式能夠解決:

       1.刪除drawable-hdpi、drawable-mdpi、drawable-ldpi三個文件夾,建立一個drawable文件夾便可;

       2.將資源文件放入assets中,由於assets中的資源系統永遠不會爲其生成id,因此不會智能縮放;

      -------------------下面介紹第二點,如何讓你的遊戲應用高清

      其實仍是在《       【Android遊戲開發二十一】Android os設備謊話分辨率的解決方案!      》中介紹過,1.6後android有了智能判斷的緣故,你獲取的屏幕寬高實際上是不許確的,詳情能夠參考       【Android遊戲開發二十一】Android os設備謊話分辨率的解決方案!      》;那麼這裏要補充一點就是:    

      若是你在AndroidMainFest 中,定義  <uses-sdk android:minSdkVersion="4" /> 就OK了!你會發現你的圖片很清楚,其實也是由於android自動縮放形成的,上面說了,通常獲取的分辨率會不正常(比正確的偏小)那麼一旦你加上這一句以後,你的分辨率就正常了,因此就明顯遊戲質量高了一個檔次。

 

       這裏再補充一下: 一旦你定義了<uses-sdk android:minSdkVersion="4" />,就是限制1.5SDK的手機沒法安裝你的程序;

 

      OK,繼續忙了,你們嘗試下吧~

 

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 ?)    

 

 

1、相關概念

a)       android支持density的版本       Android從1.6版本開始支持density(對應API Level 4)    

      b)       density             density值表示每英寸有多少個顯示點,好比240就是每英寸240個點,它是針對設備的屬性,它是屏幕物理長寬的擴展,給屏幕設置爲低密度顯示的內容少,一樣的條件下,密度小的屏幕顯示一樣的按鈕看起來大,高密度的看起來小    

c)       分辨率             是整個屏是多少點,好比800x480,它是對於軟件來講的顯示單位,以px爲單位的點    

d)       設置density的效果             不一樣density下屏幕分辨率信息,以480dip*800dip的WVGA爲例       density=120時 屏幕實際分辨率爲240px*400px             density=160時 屏幕實際分辨率爲320px*533px             density=240時 屏幕實際分辨率爲480px*800px    

2、相關代碼及設置

a)       AndroidManifest.xml             <supports-screens android:anyDensity="true"/>             <uses-sdk android:minSdkVersion="4"></uses-sdk>    

      b)       資源目錄名(android 2.0之後)       res/xxx-hdpi    當density爲240時,使用此目錄下的資源       res/xxx-mdpi    當density爲160時,使用此目錄下的資源       res/xxx-ldpi    當density爲120時,使用此目錄下的資源       res/xxx     不常後綴,爲默認設置,同xxx-mdpi       若是硬件相應的desity的目錄不存在,系統會利用存在的density自動乘以係數計算出相應的density    

c)       資源單位(layout xml文件中定義大小的單位)

                     i.              dp=dip=dx   (       Density independent pixel      )       基於屏幕密度的抽象單位,佈局時儘可能使用單位dip,少使用px               dip是             應用用於定義UI的虛擬單位,用於說明與密度無關的尺寸和位置。       dip點等價於160dpi密度中的一個物理點,密度由平臺決定,換算公式以下       pixels = dips * (density / 160)              160DPI的密度係數是1              例如 240 dpi的屏幕,1個dip點等於1.5個物理點    

                  ii.              px       設置的絕對點數, 若是使用更高density的系統, 控件就會變小    

      3、設置density       設置系統變量hw.lcd.density,可設置density    

4、實現density的關鍵源碼

a)       BitmapFactory.java

b)       ComptibilityInfo.java

相關文章
相關標籤/搜索