Android 之UI自適應解決方式

1.概況

       做爲Android開發者,最頭疼的莫過於讓本身開發的程序在不一樣終端上面的顯示效果看起來儘可能一致(固然。假設要充分利用大屏幕的優點另當別論)。在全球範圍內來說。android有着數以億計的設備,當中就不乏設備分辨率多種多樣。以及設備屏幕物理尺寸的多樣化。html

         總得來講咱們需要作的有三點。其一讓APP的每個UI中的每個View寬和高更加靈活以適應不一樣分辨率、其二對於大屏幕設備(PAD)需要有不一樣的設計,竟可能多的展現內容。獲取你整個APP的所有UI都可以作到一個佈局中來、其三圖標資源需提供不一樣尺寸(MDPI、HDPI、XHDPI、XXHDPI、XXXHDPI),你也可以圖方便僅僅提供一套較高尺寸的API,沒問題,這可能僅僅會使那些配置低的設備(或者說分辨率低,事實上實際這二者廣泛成正比)耗費不少其它的內存在載入資源圖片上面。android

 

2.官方支持

 1.圖標資源

官方建議APP中使用的圖標資源都需提供drawable-ldpi(眼下來看,已經沒有必要)、drawable-mdpi、drawable-hdpi、drawable-xhdpi。app

說到DPI(Dots Per Inch)事實上就是單位尺寸有多少個像素,計算方式就是手機分辨率寬的平方+高的平方,再開根號獲得斜對角線分辨率。ide

而後用這個除以屏幕的實際尺寸(也就是咱們常說的4寸、5寸、7寸、10寸),這個尺寸實際也是屏幕的斜對角尺寸。這樣計算出來的結果就是像素密度。像素密度越大說明手機顯示越細膩。舉個樣例HTC One分辨率是1920*1080,屏幕尺寸是4.7英寸,拿上面的公式計算一下2202/4.7=468那麼它屬於上面哪一個區域呢?android給出了一個範圍,例如如下:佈局


很是顯然HTC One 被納入xhdpi這一類裏面。字體

因此假設你的APP提供了drawable-xhdpi如下的圖標,HTC One執行你APP時會本身選擇載入那裏面的。ui


2.佈局spa

Android的五大布局各自是LinearLayout(線性佈局)、FrameLayout(幀佈局)、RelativeLayout(相對佈局)、AbsoluteLayout(絕對佈局)和TableLayout(表格佈局)。設計

當中用得最多的要數LinearLayout和RelativeLayout,FrameLayout和TableLayout可在有特效需求的頁面使用,這裏就不介紹,而AbsoluteLayout已經被標記位Deprecated since API level 3,不建議再使用。orm

線性佈局的特色是。裏面的每個view都是按順序擺放,要麼是垂直要麼是水平,誰聲明在前面誰顯示時就排在前面。

而相對佈局位置不受排放順序的限制,可以在xml中指定它位於哪一個view的上方、下方、左邊或右邊。

作自適應最關鍵的地方就在佈局上面,首先拿到需求後分析頁面採用何種佈局結構才幹更好的作到自適應,或者APP設計時就設計得比較簡單,而手機端軟件的設計規則也是越簡單越好用!在佈局上儘可能使用match_parent個wrap_content,絕對不要使用px(固然假設你的APK僅僅需要支持某一種分辨率除外),非要設置詳細大小時使用dp作單位,這樣才幹在不一樣DPI但物理尺寸大小同樣的手機上面通用。

但都用dp並不能知足同一時候適應手機和平板(物理尺寸存在較大差別)。因爲平板的物理尺寸比較大通常是7寸以上。舉個樣例。兩個Button將其大小設置爲width 50dp height 50dp,它在800*480 尺寸爲4寸的手機上面顯示效果例如如下:

 

而在1024*600的七寸平板上面顯示效果例如如下:

 

 

很是顯然在平板上面顯示效果感受過小了。爲何會出現如此差別,咱們可以經過計算得出答案。800*400 4寸 DPI是230。normal狀態下DPI是160,據此咱們可以算出50dp在這個800*480 4寸設備上面佔用的像素是230/160*50 = 72px ,顯然這個寬度僅僅佔到整個屏幕寬度的72/480=0.15。再看看截圖,應該幾乎相同是這麼個比例吧。假設是在1024*600的7寸(DPI是170)設備上面50dp佔用的像素是170/160*50=53px,這樣整個button佔領屏幕的寬度就僅僅有53/600=0.09,也就是如截圖看到的同樣佔用很是小的一坨。

因此,經過dp做爲單位不能解決不一樣尺寸設備的自適應問題,相同android也提供了對應的解決的方法,在android3.2 (API 13)曾經對屏幕大小作了例如如下分類:


要想在佈局文件裏區分不一樣尺寸設備可以經過layout-small、layout-normal、layout-large和layout-xlarge,依據咱們剛纔計算的值,僅僅需在layout-large中指定button的大小爲x這個x的值可以經過公式算出來x*(170/160)/600=0.15  x = 600*0.15/(170/160)=95dp,再看下效果例如如下:

 

這樣就它們顯示起來的效果就差點兒同樣了。同一時候,不光是大小,顯示的位置都可以依據屏幕的大小作不一樣的顯示。普通狀況下你需要維護layout layout-large和layout-xlarge三套佈局文件,在android 3.2之後官方又提供了更加精確的尺寸大小區分辦法。sw<N>dp,當中sw指的是長和寬中的較小者。比方1024*600的7寸,sw的計算方式是600/(170/160)=565dp,但實際是不正確的,參考網頁《官方六》中的描寫敘述:

Note: The sizes that you specify using thesequalifiers are not the actual screen sizes. Rather, the sizes arefor the width or height in dp units that are available to youractivity's window. The Android system might use some of the screen forsystem UI (such as the system bar at the bottom of the screen or the status barat the top), so some of the screen might not be available for your layout.Thus, the sizes you declare should be specifically about the sizes needed byyour activity—the system accounts for any space used by system UI whendeclaring how much space it provides for your layout. Also beware thatthe Action Bar isconsidered a part of your application's window space, although your layout doesnot declare it, so it reduces the space available for your layout and you mustaccount for it in your design.

因此說需要注意的是計算sw時會有必定得區間浮動,咱們需要儘可能定義小些。比方565dp假設你定義爲sw565dp。但實際是sw564dp,那麼就不會走到sw565dp裏面去了。而是採用向下找近期的原則,假設都沒找到就使用默認的layout。

       對於官方爲何會引入sw這個概念,是因爲large xlarge已經不能適應各類廠商太多的中間尺寸,比方5.5 、5.七、 6 、 6.5等等,假設是android3.2下面。這些將全部被納入large的範疇。這種話5.5和7寸設備顯示的效果就會有些出入,固然不會有很是大出入。

爲了知足人們對設計的精益求精,在android3.2之後的設備中都可以使用sw來作更細的劃分。如sw480dp sw600dp sw720dw sw1024dp等等。

      固然爲了不維護如此多的layout佈局文件咱們還可以用另外的版本號來完畢自適應的動做。如上面的樣例,每個button都是佔屏幕寬度的0.15,咱們可以用layout_weight權重這一律念,設置該button的權重爲0.15就能夠,它就會在每個設備上面達到相同的效果—均佔屏幕寬度的0.15,高也是同理。對與寬高比例一致的設備這是一個不錯的選擇,但對與不一樣寬高比的設備,全然使用layout_weight來作自適應顯然是不能達到效果的,比方800*480和854*480的設備,假設高採用相同的weight,854的高確定會顯得拉伸。假設button上面有背景圖片。則圖片會變形。

有一個小技巧可以解決此問題。就是用ImageView來取代Button,同一時候將背景圖片設置爲android:src。曾經景的模式顯示。這樣可以利用imageview的屬性,使圖片保持原始的比例填充。

     

3.數值

佈局文件裏會用到各類數值。如view的寬、高,字體的大小padding大小,magin大小等均可以在values目錄中定義當中就包含strings.xml dimens.xml styles.xmlcolor.xml等等,固然跟自適應相關的就是dimens.xml。這裏面定義了各類view屬性的大小,好比button的高爲50dp可以在dimens裏面定義<dimen name="btn_size">50dp</dimen>而後將button的android:layout_width="@dimen/btn_size "。在佈局部分咱們講到用layout-large layout-sw600dp等來區分不一樣屏幕大小的設備,相同在values裏面也可以加上values-largevalues-sw600dp等來區分。比方最開始的樣例裏面咱們可以僅僅定義一個layout 將button的寬高都設置爲@dimen/ btn_size,而後定義一個values/dimen.xml 和一個values-large/dimen.xml,分別寫上<dimen name="btn_size">50dp</dimen>和<dimen name="btn_size">95dp</dimen>,這和寫多個layout效果是同樣的。但我我的認爲假設頁面相對照較簡單。在values裏面下功夫比寫多個layout要簡單些。

3. 擴展

有時咱們APP需要支持到比較舊的API版本號。但咱們有想用到一些比較高級的API裏面的功能,這時咱們可以在values後面加上-v<xx>如values-v11。當中11就是API版本號,也就是11以上API的設備就會採用values-v11裏面的內容。就比方API 11裏面增長了Action Bar的功能。那麼假設你想利用這個特性,可以在values-v11裏面定義一個style.xml,繼承自action bar相關的style,而在values裏面的style.xml中定義不支持action bar的style。但在佈局中用其它view來模擬action bar的效果。

4.總結

對與UI自適應總結一下主要是兩點。一樣屏幕尺寸不一樣分辨率以及不一樣屏幕尺寸一樣分辨率。對於前者,僅僅需在佈局中用到單位的地方所實用dp就能夠解決(有條件的話drawable最好能提供不一樣分辨率icon,實在不行。提供贊成範圍內儘可能大分辨率圖片)。對於後者,則需要依據尺寸的等級寫不一樣的layout文件或者values文件。這個需依據項目的詳細負責程度來自由選擇。

相關文章
相關標籤/搜索