Android 屏幕適配之dimens適配
在過去多個項目中一直使用dimens適配,這種適配方式的優點很明顯,不用管什么dp還是dpi這些東西,只需要以一種屏幕分辨率為基准(例如1280x720,相當於把屏幕寬分成720份,高分成1280份),生成對應屏幕分辨率的的dimens文件即可完成適配,缺點也比較明顯,就是一種分辨率就需要一套dimens文件,所以dimens文件會比較多;
例如這里我們以1280x720的屏幕分辨率為基准那么values-1280x720文件夾下面的dimens.xml文件如下:
-
<dimen name="x1">1px</dimen>
-
<dimen name="x2">2px</dimen>
-
<dimen name="x3">3px</dimen>
-
<dimen name="x4">4px</dimen>
-
省略若干行...
-
<dimen name="x1279">1279px</dimen>
-
<dimen name="x1280">1280px</dimen>
-
<dimen name="x1">1.5px</dimen>
-
<dimen name="x2">3px</dimen>
-
<dimen name="x3">4.5px</dimen>
-
<dimen name="x4">6px</dimen>
-
省略若干行...
-
<dimen name="x1279">1918.5px</dimen>
-
<dimen name="x1280">1920px</dimen>
-
<dimen name="x1">2px</dimen>
-
<dimen name="x2">4px</dimen>
-
<dimen name="x3">6px</dimen>
-
<dimen name="x4">8px</dimen>
-
省略若干行...
-
<dimen name="x1279">2558px</dimen>
-
<dimen name="x1280">2560px</dimen>
在適配過程中比較常見的問題是虛擬按鍵的問題,這里重點說一下:有些手機有虛擬按鍵,例如華為的很多手機都有,有些手機沒有,有虛擬按鍵的手機在適配過程中會出現一些問題,下面以華為 honor V8為例說一下這個問題
-
/**
-
* @param context
-
* @return 獲取屏幕原始尺寸高度,包括虛擬功能鍵高度
-
*/
-
public static int getTotalHeight(Context context) {
-
int dpi = 0;
-
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-
Display display = windowManager.getDefaultDisplay();
-
DisplayMetrics displayMetrics = new DisplayMetrics();
-
-
Class c;
-
try {
-
c = Class.forName( "android.view.Display");
-
-
Method method = c.getMethod( "getRealMetrics", DisplayMetrics.class);
-
method.invoke(display, displayMetrics);
-
dpi = displayMetrics.heightPixels;
-
} catch (Exception e) {
-
e.printStackTrace();
-
}
-
return dpi;
-
}
-
/**
-
* @param context
-
* @return 獲取屏幕內容高度不包括虛擬按鍵
-
*/
-
public static int getScreenHeight(Context context) {
-
WindowManager wm = (WindowManager) context
-
.getSystemService(Context.WINDOW_SERVICE);
-
DisplayMetrics outMetrics = new DisplayMetrics();
-
wm.getDefaultDisplay().getMetrics(outMetrics);
-
return outMetrics.heightPixels;
-
}
調用后得到的結果是 總高度 : 2560 內容高度 : 2408 虛擬按鍵 : 152
如果想要適配該機型,其實也很簡單,只需要把原來的values-2560x1440文件夾復制一份重新名為values-2408x1440即可,在使用dimens適配過程中,若遇有類似虛擬按鍵問題可照此處理,親測完美適配!
對於dimens文件這里我想說一下,其實一個文件夾下面一個dimens文件即可,沒必要弄兩個(lay_x和lay_y,網上不少博客是使用兩個dimens文件,至少分辨率是16:9的手機用一個dimens文件是可以的,因為lay_y.xml里面的內容已經包括lay_x.xml文件中的了)
減少dimens文件還有一個方法:對於一個主流的分辨率只要留虛擬按鍵高度最高的那組dimens文件即可,什么意思呢?比如說1920x1080分辨率,有多款機型都是這個分辨率,只不過是虛擬按鍵高度不同,你可能需要創建1788x1080,1812x1080,1776x1080...等多套dimens文件,其實大可不必,只需要1776x1080這一套就夠了,因為系統找不到對應尺寸的dimens文件,會使用比它略小的分辨率的dimens文件,如此一來我們的dimens文件會大大減少的。
下面是使用dimens適配的簡單效果圖:
我們把手機寬度分為720份,360則正好是手機屏幕寬度的一半,適配后的效果如上所示。
上面內容只是我在項目開發過程中使用dimens適配的簡單總結,使用中若遇到問題歡迎交流探討,若文中有不當之處也歡迎大家批評指正!
該生成器使用十分簡單,下面用兩張截圖介紹使用方法:
注意:該生成器得到的dimens文件的單位是dp,我們需要的是px作為單位,只需要把saveDimens.xml文中的內容做一次查找替換就可以了。(這是個小bug,不過不妨礙我們使用)
下面是我Demo中使用的dimens文件:
主要是針對1280x720、1920x1080和2560x1440的三個主流分辨率做了適配,我這里是以1280x720為基准,即把屏幕寬分為720份、高分為1280份。
這里我說的更明白一點:以1920x1080分辨率為例,只要你的android設備是這一分辨率的,屏幕總高度去除虛擬按鍵高度之后只要≥1788就能夠適配。
上面是我測試Demo的apk下載地址,您可以下載試一下看看是否能夠適配您的機型。
上圖是我用Android studio中的模擬器測試的結果,該模擬器的分辨率是1920x1080,很明顯它有虛擬按鍵,去除虛擬按鍵之后的高度是1794≥1788,故而在適配范圍內,從圖中效果也可以看出已經完美適配,如果您的機型也是1920x1080的(其它分辨率原理也一樣),測試發現360x360的淺紅色方塊區域沒有占手機屏幕寬度的一半,說明未能成功適配,很可能是因為您的手機虛擬按鍵高度>132即您的內容高度<1788,這時候不用驚慌,看看屏幕中得到的內容高度是多少,假如是1776那就把values-1788x1080文件夾的名稱改為values-1776x1080,重新運行你會發現奇跡發生了...
如果你不相信,那你就把values-1788x1080文件夾刪掉,用studio的模擬器或者帶有虛擬按鍵的1920x1080的真機測一下,如果不能適配,你再把刪掉的文件夾加進去,重新運行看看效果吧!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
到這dimens適配大致已經介紹完了,想必讀者也已經領會了解決虛擬按鍵的竅門,那么知道了這些之后可以在正式項目中使用dimens適配了嗎?
好像還不行,還有一些坑我覺得還是有責任要告訴大家的:
★ values文件夾下面最好也創建一個默認的dimens文件(若是找不到對應分辨率的dimens文件,系統默認使用該dimens文件,內容使用720×1280那個dimens即可)
★ 盡量把所有分辨率的dimens文件都創建出來(各種分辨率的都考慮到,你的應用才會適配的完美)
★ 多使用布局屬性做適配(match_parent,wrap_content,以及線性布局的權重等等多結合這些屬性做適配)
理解dimens文件適配的精髓,掌握解決虛擬按鍵問題的訣竅再結合傳統布局的屬性這樣你的 dimens 適配之路才能走的輕松、坦盪!