android開發:在不同解析度,不同螢幕密度dpi的平板上的字型大小和佈局的自適應
最近在這家公司做一些android裝置上的開發,使用了幾款平板進行真機除錯,面對不同解析度,不同螢幕密度dpi的裝置,碰到了一些和虛擬機器不太一樣的情況,在這裡和大家分享一下。
1.一些名詞的簡單理解,後面會有詳細說明
(1)螢幕尺寸:單位英寸(inch),指的是螢幕對角線長度。
(2)螢幕密度:單位dpi,指的是每inch上可以顯示多少畫素點即px。
(3)螢幕解析度:單位px * px,如1280×800,我使用的小米853×480等,指的是一屏顯示多少畫素點。
(4)螢幕無關畫素:單位dp/dip,指的是自適應螢幕密度的畫素,用於指定控制元件寬高。
(5)刻度無關畫素:單位sp,指的是自適應字型的畫素,用於指定文字大小。
2.關於螢幕密度dpi
密度可以理解為每英寸包含的畫素個數(單位是dpi),如果螢幕物理密度是160dpi時,dp和px是等效的。
2.1先說下螢幕密度的計算吧
一個手機或者平板,拿到手就可以看到它的尺寸和解析度,我接觸的幾款android裝置有一下幾種:
(1)小米1(最早出的那一款)4寸螢幕,853×480的解析度
(2)聯想ideatab s6000 10.1寸,1280×800
(3)某款android平板,大小引數規格單找不到了,反正是mdpi 800×480
思路很簡單:由於給了螢幕對角線的長度10.1英寸,再計算對角線上有多少個畫素點,就可以計算每英寸包含的畫素點數。
已(2)為例,看看怎麼計算螢幕密度:√ (1280²+800²
即其螢幕密度為150dpi。
2.2 android系統對螢幕密度的歸一化處理
如圖,android提供ldpi,mdpi,hdpi,xhdpi,xxhdpi等不同螢幕密度級別,這些都是經過歸一化處理的
ldpi低密度屏,螢幕密度為120dpi, 1dp = 0.75px (由於畫素點是物理點,所以用2個畫素點來顯示3個dp的內容)
mdpi中密度屏,螢幕密度160dpi 1dp = 1px
tvdpi電視密度屏,螢幕密度213dpi 1dp = 1.33px
hdpi高密度屏,螢幕密度240dpi 1dp = 1.5px
xhdpi極高密度屏,螢幕密度320dpi
1dp = 2px
小米1螢幕密度為244dpi,屬於hdpi級別;(2)款平板密度為150dpi,歸一化屬於mdpi級別
這樣就為你的裝置計算好了密度級別,這個很重要
3.屏幕布局layout.xml的適配
3.1不考慮橫豎屏切換
參考自:http://www.cnblogs.com/mybkn/articles/2535519.html 點選開啟連結
作者給了4種方法,我就copy下我借鑑的第一種方法吧:
目前最為推薦的Android多螢幕自適應解決方案。
該屬性的作用是決定控制元件在其父佈局中的顯示權重,一般用於線性佈局中。其值越小,則對應的layout_width或layout_height的優先順序就越高,一般橫向佈局中,決定的是layout_width的優先順序;縱向佈局中,決定的是layout_height的優先順序。 傳統的layout_weight使用方法是將當前控制元件的layout_width和layout_height都設定成fill_parent,這樣就可以把控制元件的顯示比例完全交給layout_weight;這樣使用的話,就出現了layout_weight越小,顯示比例越大的情況。不過對於2個控制元件還好,如果控制元件過多,且顯示比例也不相同的時候,控制起來就比較麻煩了,畢竟反比不是那麼好確定的。 於是就有了現在最為流行的0px設值法。看似讓人難以理解的layout_height=0px的寫法,結合layout_weight,卻可以使控制元件成正比例顯示,輕鬆解決了當前Android開發最為頭疼的碎片化問題之一。 先看下面的styles(style_layout.xml)<?xml version="1.0" encoding="utf-8"?> <resources><!-- 全螢幕拉伸--><style name="layout_full"><item name="android:layout_width">fill_parent</item><item name="android:layout_height">fill_parent</item></style><!-- 固定自身大小--><style name="layout_wrap"><item name="android:layout_width">wrap_content</item><item name="android:layout_height">wrap_content</item></style><!-- 橫向分佈--><style name="layout_horizontal" parent="layout_full"><item name="android:layout_width">0px</item></style><!-- 縱向分佈--><style name="layout_vertical" parent="layout_full"><item name="android:layout_height">0px</item></style></resources>可以看到,layout_width和layout_height兩個屬性被我封裝成了4個style 根據實際佈局情況,選用當中的一種,不需要自己設定,看過我前一個ActivityGroup的Demo的同學應該非常熟悉了 然後我的Demo的佈局如下(weight_layout.xml)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" style="@style/layout_full" android:orientation="vertical"><LinearLayout style="@style/layout_vertical" android:layout_weight="1" android:orientation="horizontal"><View style="@style/layout_horizontal" android:background="#aa0000" android:layout_weight="1"/><View style="@style/layout_horizontal" android:background="#00aa00" android:layout_weight="4"/><View style="@style/layout_horizontal" android:background="#0000aa" android:layout_weight="3"/><View style="@style/layout_horizontal" android:background="#aaaaaa" android:layout_weight="2"/></LinearLayout><LinearLayout style="@style/layout_vertical" android:layout_weight="2" android:orientation="vertical"><View style="@style/layout_vertical" android:background="#ffffff" android:layout_weight="4"/><View style="@style/layout_vertical" android:background="#aa0000" android:layout_weight="3"/><View style="@style/layout_vertical" android:background="#00aa00" android:layout_weight="2"/><View style="@style/layout_vertical" android:background="#0000aa" android:layout_weight="1"/></LinearLayout> </LinearLayout>
整個介面佈局看起來非常直觀,只是巢狀的邏輯要自己理下。顯示效果如下圖,其中左面一個是480x800的介面,右面的是320x480的介面(後面的圖也如此),可以看出顯示比例和程式碼中完全一致,我就不多說了,大家對照下就能看出來了。
3.2考慮橫豎屏切換
思路是:在res目錄下新建立兩個資料夾:layout-port和layout-land.
把橫屏的xml放到layout-land裡,把豎屏的放到layout-port裡,取一樣的名字。
具體demo木有,boss要求我把螢幕寫成橫屏,寫死了
3.3圖片的適配
準備不同大小的圖片資源,起一樣的名字放在對應的drawable- dpi資料夾下,
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitCenter"
android:src="@drawable/xxx"/>
這4個屬性必不可少,簡單的介紹一下,充滿布局,scalType屬性設定為fitCenter保證放大長寬比例,src而不是background
再就是圖示,icon的一些說明:
ldpi (120 dpi) mdpi (160 dpi) hdpi (240 dpi) xhdpi (320 dpi)
36 x 36 px 48 x 48 px 72 x 72 px 96 x 96 px
4.字型大小的適配
思路是如上圖,為不同解析度,不同密度準備一套字型大小的尺寸
在values-xxx-xxx資料夾下建立dimen。xml檔案:<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="size_title">20sp</dimen>
<dimen name="size_name">18sp</dimen>
<dimen name="size_code">10sp</dimen>
</resources>
有一些我在配置過程中碰到的問題和大家分享一下:
1.資料夾命名:
如上圖,有些錯誤的資料夾,我的結論是解析度x號前面的數值要比後面的大,不然系統無法識別,
注意:乘號的輸入法,千萬別用漢字輸入法下的x,不然系統無法系別,不要問我為什麼,我是不會告訴你這玩意花了我起碼3個小時才搞明白
2.系統會自動匹配values資料夾
舉個例子,之前提到的(2)1280x800的,如果你建立values-mdpi-1250x800,values-mdpi-1200x800,(注意了這兩個都不是1280x800的),最後真機聯調的時候,顯示的是比真實解析度小的最大的那套尺寸即values-mdpi-1250x800,而不是1200x800,這點上虛擬機器和真機有很大的區別,xml檢視只會找1280x800的尺寸,如果沒有,他就顯示預設大小的字型。
可以參考下這一篇:點選開啟連結http://www.cnblogs.com/zealotrouge/archive/2012/11/23/2784774.html
3。如果系統系統自動匹配的時候沒有找到最小的尺寸,就會報錯
所以建議在values下dimen.xml下儲存一份最小的字型尺寸,再難看也好過報錯,是吧
5.字型適配的其他思路
用圖片代替字型,但是EditText有點難搞...
暫時總結的就這麼多了,第一次發原創~~~
爭取以後寫的更好