android基礎—尺寸單位和屏幕適配

1. 引論html

衆所周知,Android機型尺寸各類各樣,因而屏幕適配就成了Android開發中很重要的一環。Android屏幕適配可能一些開發者都會遇到這樣的問題,、java

今天就來分享下屏幕適配,其實Android屏幕適配也能夠很簡單。android

參考:1. http://www.cnblogs.com/yaozhongxiao/archive/2014/07/14/3842908.html網絡

         2. http://www.cnblogs.com/ycxyyzw/p/3889939.htmlide

2. Android下尺寸的基本單位函數

① px 像素工具

是英文單詞pixel的縮寫,意爲像素,屏幕上的點。咱們一般所說的分辨率如480X800就是指的像素。佈局

px是個絕對單位,在不一樣尺寸的手機設備下,像素固定顯示效果就是同樣的!字體

在設計領域中,像素是用來計算數碼影像的最小單位。計算機中顯示的圖像並不是連續的線條組成,而是由許多肉眼看不見的小點組成。google

若是把影像放大數倍,會發現這些連續色調實際上是由許多色彩相近的小點所組成,這些小點就是構成影像的最小單位「像素」。因爲是最小的獨立顯示單位,px均爲整數,不會出現0.5px的狀況。

② in 英寸

表示英寸,是屏幕的物理尺寸。每英寸等於2.54釐米。例如咱們常常說的手機屏幕大小有,5(英)寸、4(英)寸就是指這個單位。這些尺寸是屏幕的對角線長度。若是手機的屏幕是4英寸,表示手機的屏幕

(可視區域)對角線長度是4 X 2.54 = 10.16釐米。

應該明白咱們常說的屏幕是4寸指的是:屏幕對角線是4寸

③ dpi  每英寸包含像素個數

dpi是Dots Per Inch的縮寫, 每英寸點數,即每英寸包含像素個數。好比320X480分辨率的手機,寬2英寸,高3英寸, 每英寸包含的像素點的數量爲320/2=160dpi(橫向)或480/3=160dpi(縱向),160

就是這部手機的dpi,橫向和縱向的這個值都是相同的,緣由是大部分手機屏幕使用正方形的像素點。常見取值 120,160,240。通常稱做像素密度,簡稱密度

④ density 屏幕密度

屏幕密度,density和dpi的關係爲 density = dpi/160,爲了與dpi稱呼區別通常叫作屏幕密度,或者直接教density

⑤ dp 設備獨立像素

也即dip,設備獨立像素,device independent pixels的縮寫,Android特有的單位,常見取值 1.5 , 1.0 。和標準dpi的比例(160px/inc)即在屏幕密度dpi = 160屏幕上,1dp = 1px。

⑥ sp 放大像素

與sp相似(設備獨立),主要用於字體顯示,和dp的區別是它能夠根據用戶的字體大小偏好來縮放。

注意點1: pixs = dips * (dpi/160) 也就是說相同的dip(dp)在不一樣的屏幕密度下會表明不一樣個像素點

              如: 定義一個矩形10 x 10dip.在分辨率爲160dpi的屏上,好比G1,正好是10 x 10像素。而在240 dpi的屏,則是15 x 15像素

注意點2:根據google的推薦,統一使用dip,字體則使用sp,這樣更好看

3. 各單位的轉換

① 計算dpi與屏幕密度density

dpi = (px/inch) /(160 px/inch)

好比一個機器,屏幕4寸,分辨率480X800,他的dpi能算麼。

由於不知道邊長,確定不能分開算,4 寸是對角線長度,那直接用勾股定理算對角線像素,除以4,算出來大概是 dpi = 233 像素/英寸。

那麼density就是 (233 px/inch)/(160 px/inch)=1.46 左右

順帶說下,android默認的只有3個dpi,low、medium和high,對應 120、160、240,若是沒有特別設置,全部的dpi都會被算成這3個,其中的default就是160。

② dp與px 設備獨立像素與像素的轉換

咱們寫佈局的時候,確定仍是要知道1個dp到底有多少px的。

換算公式以下: dp = (DPI/(160像素/英寸))px = density px ,也就是 屏幕密度×像素 = 獨立設備像素

假設dpi是240 像素/英寸 , 那麼density就是1.5,那麼就是 1dp=1.5px 

 ③ 爲何咱們在佈局時儘可能要用dip,而不是px?

http://www.cnblogs.com/yaozhongxiao/archive/2014/07/14/3842908.html

4. android Drawble目錄

  • drawable-ldpi (dpi=120, density=0.75)

  • drawable-mdpi (dpi=160, density=1)

  • drawable-hdpi (dpi=240, density=1.5)

  • drawable-xhdpi (dpi=320, density=2)

  • drawable-xxhdpi (dpi=480, density=3)

能夠看到drawable文件夾,分別對應不一樣的dpi

古老方案:市面上的一些Android教程大多都是教的是爲每種dpi都出一套圖片資源,這個當然是一種解決辦法,但同時也是一種很是笨的方法,爲美工或者設計增長了很多的工做量不說,同時也會讓你的apk包

變的很大。那麼有沒有什麼好的方法既能保證屏幕適配,又能夠最小佔用設計資源,同時最好又只使用一套dpi的圖片資源呢?

 

首先必須清楚一個自動渲染的概念,Android SDK會自動屏幕尺寸選擇對應的資源文件進行渲染,如SDK檢測到你手機dpi是160的話會優先到drawable-mdpi文件夾下找對應的圖片資源,注意只是優先,假設

你手機dpi是160,可是你只在xhpdi文件夾下有對應的圖片資源文件,程序同樣能夠正常運行。因此理論上來講只須要提供一種規格的圖片資源就ok了,若是隻提供ldpi規格的圖片,對於大分辨率的手機若是把

圖片放大就會不清晰,因此須要提供一套你須要支持的最大dpi的圖片,這樣即便用戶的手機分辨率很小,這樣圖片縮小依然很清晰。

 

② 重點須要明白: 

 

  <View 
           android:layout_height="1dip"
           android:layout_width="100dip"/>

該View在密度爲160dip的屏幕上顯示的長度爲100px(像素)長,而在320dip的屏幕上它的長度將爲200px。

在圖片處於drawable文件夾內時,也須要作這種轉換。

假如在drawable-mdpi的文件夾內有一張22*44的圖片,經過程序將其讀入系統中時,假設屏幕密度爲320dip,那它在內存中的大小將是44*88。

總結:   本機系統的DPI > 圖片所在文件夾的DPI  圖片將會被放大

          本機系統的DPI < 圖片所在文件夾的DPI  圖片將會被縮小

目前主流作法是將圖片放置在drawable-hdpi文件夾內,該文件夾對應的density是240dip,但其實如今的手機通常都是320dip甚至480dip了,

因此放置在hdpi文件夾內的圖片在顯示時都是已經自動拉伸過了。

③ 當圖片是從其餘地方而來,如直接讀取sd卡或assert文件夾內的圖片或網絡下載來時的狀況

首先獲取的不是drawbale對象而是個bitmap對象,該bitmap對象的width和height對應的是圖片的真實像素大小。

而將bitmap對象轉換爲drawable時,除非咱們手動設置了目標density,不然不進行縮放。

BitmapDrawable bmpDrawable = new BitmapDrawable(bitmap);

使用這個構造函數,默認的density是160,該構造函數已經被摒棄了,推薦使用下一個

BitmapDrawable bmpDrawable = new BitmapDrawable(getResources(),bitmap);

該構造函數會經過getResources獲取到手機的density,將其設置爲默認的density。

getResources().getDisplayMetrics().densityDpi

若咱們須要進行縮放,能夠經過下述方法設置目標density。

bmpDrawable.setTargetDensity(160)

在320dip長度的屏幕上,該bmpDrawable將會縮小爲一半。

        

5. android下尺寸描述工具類

① 獲得屏幕寬和高

  public static int getWidth(Context context){ 
         WindowManager wm=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
         DisplayMetrics outMetrics = new DisplayMetrics(); 
         wm.getDefaultDisplay().getMetrics(outMetrics); 
         return outMetrics.widthPixels; 
    

DisplayMetrics的toString()方法以下:

複製代碼
    @Override
    public String toString() {
        return "DisplayMetrics{density=" + density + ", width=" + widthPixels +
            ", height=" + heightPixels + ", scaledDensity=" + scaledDensity +
            ", xdpi=" + xdpi + ", ydpi=" + ydpi + "}";
    }
複製代碼

② dp與dx的轉化

** * 根據手機的分辨率從 dip 的單位 轉成爲 px(像素) */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } /** * 根據手機的分辨率從 px(像素) 的單位 轉成爲 dp==dip */ public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); }

相關文章
相關標籤/搜索