前言
一款Android 屏幕適配方案。
網上關於屏幕適配的文章已經鋪天蓋地了,爲什麼我還要講?因爲網上現在基本都是使用px適配,即每種屏幕分辨率的設備需要定義一套dimens.xml文件。再加上有些手機還有虛擬按鍵(例如華爲),這樣就還需要每個有虛擬按鍵的設備加多一套dimens.xml文件,再加上平板那些你會發現dimens.xml文件所佔的體積已經超過2M了!這絕對不是我們想要的。
我這裏要講的是使用dp來進行適配(Google推薦的也是這種方式),使用這種方式項目中多套dimens.xml文件才佔幾百K,而且根本不用考慮虛擬按鍵的問題。這種方案已經在自己多個項目中應用過了,經過幾十臺手機測試過,基本不會出現適配有問題的情況。製作生成對應dimens.xml文件插件的作者(後面會講)android阿杜也說過他在待過的兩家大公司實踐過,所以請放心使用。
爲什麼要進行Android屏幕適配?
關於爲什麼要進行Android屏幕適配,什麼是dp、dpi這些概念我就不去一一講解了,網上很多文章。這裏我推薦幾篇講的比較好的:
px與dp適配的原理
px適配原理:
根據設備屏幕的分辨率各自寫一套dimens.xml文件,然後根據一個基準分辨率(例如720x1080),將寬度分成720份,取值爲1px——720px,將高度分成1080份,取值爲1px——1080px。生成各自dimens.xml文件對應的值。dp適配原理:
dp適配原理與px適配一樣,區別就在於px適配是根據屏幕分辨率,即拿px值等比例縮放,而dp適配是拿dp值來等比縮放而已。
問題:
既然原理都一樣,都需要多套dimens.xml文件,爲什麼說dp適配就比px適配好呢?
因爲px適配是根據屏幕分辨率的,Android設備分辨率一大堆,而且還要考慮虛擬鍵盤。而dp適配無論手機屏幕的像素多少,密度比值多少,80%的手機的最小寬度dp值(widthPixels / density)都爲360dp,這樣就大大減少了dimens.xml文件。-
px適配會根據設備的分辨率去找對應的dimens.xml文件(如下圖,運行在分辨率爲1920x1080的手機上,系統會自動找到對應的values-1920x1080文件),那dp適配呢?
[圖片上傳失敗...(image-86fd53-1541728256699)]
dp適配也是一樣的,只不過dp適配是根據“最小寬度(Smallest-width)限定符”來找的,需要注意的是“最小寬度”是不區分方向的,即無論是寬度還是高度,哪一邊小就認爲哪一邊是“最小寬度”。所以如果當前設備最小寬度(以 dp 爲單位)爲400dp,那麼系統會自動找到對應的values-sw400dp文件夾下的dimens.xml文件,如圖
[圖片上傳失敗...(image-8967ad-1541728256699)]
獲取設備最小寬度代碼,
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int heightPixels = dm.heightPixels;
int widthPixels = dm.widthPixels;
float density = dm.density;
float heightDP = heightPixels / density;
float widthDP = widthPixels / density;
float smallestWidthDP;
if(widthDP < heightDP) {
smallestWidthDP = widthDP;
}else {
smallestWidthDP = heightDP;
}
使用步驟
1、以某一widthDP爲基準,生成所有設備對應的dimens.xml文件
生成這些文件當然不會手動去寫,網上已經有大神android阿杜提供了自動生成工具。
工具使用步驟:
- 在Android Studio中安裝ScreenMatch插件,如圖:
[圖片上傳失敗...(image-fdee03-1541728256699)]
- 在項目的默認values文件夾中需要一份dimens.xml文件
我在github源碼已經提供了一份,直接複製過來即可。
[圖片上傳失敗...(image-de366b-1541728256699)]
github地址:ScreenAdaptation
- 執行生成
插件安裝好後,在項目的任意目錄或文件上右鍵,選擇ScreenMatch選項。如圖:
[圖片上傳失敗...(image-578b15-1541728256699)]
然後選擇在哪個module下執行適配。
即基於哪個module下的res/values/dimens.xml文件作爲基準dimens.xml文件,生成的其他尺寸dimens.xml文件放在哪個module下。
[圖片上傳失敗...(image-48dbb3-1541728256699)]
點擊確定就會執行生成命令,如下代表生成成功。
[圖片上傳失敗...(image-ff6d3c-1541728256699)]
然後再看看res目錄下會自動生成一堆dimens.xml文件,如下:
[圖片上傳失敗...(image-e4114a-1541728256699)]
通過上面的步驟就已經生成了所有設備對應的dimens.xml文件。
因爲默認生成的是下列最小寬度dp的dimens.xml文件
384,392,400,410,411,480,533,592,600,640,662,720,768,800,811,820,960,961,1024,1280,1365,如果不需要或者需要增加某些dp值的dimens.xml文件,則需要修改配置文件,即screenMatch.properties文件(修改前先刪除之前生成的全部dimens.xml文件)。配置文件在我們執行完成上面的命令後,會在項目的目錄下自動生成,如下:
[圖片上傳失敗...(image-d7d77-1541728256699)]
打開文件,修改下面的值即可。如下只需要適配384,392,400,410,411的值,不需要適配480,533,592,600,640,662,720,768,800,811,820,960,961,1024,1280,1365的值
[圖片上傳失敗...(image-92e18-1541728256699)]
其中base_dp=360代表widthDP基準值,一般都是360dp,不建議更改,除非你對屏幕適配原理有深刻的見解。
當然!這些步驟你可以全部都不用做。直接複製我github上的各個dimens.xml文件到你項目即可!這些都是我在真實項目中使用的。
2、根據設計圖標註,在佈局寫上對應的值。
在安卓中,系統密度爲160dpi的中密度手機屏幕爲基準屏幕,即320×480的手機屏幕。在這個屏幕中,1dp=1px。320x480分辨率對應的其他分辨率的比例如下:
[圖片上傳失敗...(image-3f8d15-1541728256699)]
圖片來源:UI設計師不可不知的安卓屏幕知識
所以,如果UI給的是720x1280分辨率的圖, 那麼dp = px / 2, 給的是1080x1920分辨率的圖,那麼 dp = px / 3,即根據比例即可。
舉例:UI在720x1280上做的圖,其中一個按鈕的寬高分辨爲:寬720px,高爲100px,字體大小爲30px,在佈局中則這樣使用:
<Button
android:layout_width="@dimen/dp_360"
android:layout_height="@dimen/dp_50"
android:textSize="@dimen/sp_15"/>
代碼中動態設置dp或sp:
如果需要在代碼中動態設置dp或sp,則需要通過getDimension()方法獲取對應資源文件下的dp或sp值再設置(具體參考github上的demo)。如下:
/*獲取sp值*/
float pxValue = getResources().getDimension(R.dimen.sp_15);//獲取對應資源文件下的sp值
int spValue = ConvertUtils.px2sp(this, pxValue);//將px值轉換成sp值
mTvShowParams.setTextSize(spValue);//設置文字大小
/*獲取dp值*/
float pxValue2 = getResources().getDimension(R.dimen.dp_360);//獲取對應資源文件下的dp值
int dpValue = ConvertUtils.px2dp(this, pxValue2);//將px值轉換成dp值
怎麼適配其他module?
- 問題:在項目的其他module中怎麼實現適配?難道也要多套dimens?
- 解決:並不需要多套dimens,只需要在values文件夾下有一套與app module一樣的dimens文件即可達到適配。因爲經過編譯,所有module中的dimen數據都會統一歸類到主module(即app module)中的values/dimens.xml文件中了,然後系統又會根據你設置的值去找對應values-swxxxdp文件夾下的dimens.xml文件中的值。
- 驗證:在項目中建一個module,然後隨便取一個dimens.xml文件中的值進行打印,分別運行在不同widthDP的設備上(用模擬器即可)觀察打印的結果發現確實是這樣的。
最後非常感謝大神android阿杜提供的插件,具體的dp適配與插件原理可以去看看他寫的文章。
github地址:ScreenAdaptation
參考資料:
- Android屏幕適配全攻略(最權威的官方適配指導)
- Android 屏幕適配:最全面的解決方案
- Android 屏幕適配方案
- Android dp方式的屏幕適配工具使用(Android Studio插件方式)
作者:wildma
鏈接:https://www.jianshu.com/p/1302ad5a4b04
來源:簡書
這是轉載別人的東西。樓主親測。還是可以的。上面的鏈接就是作者本人的。