本項目已經(jīng)上傳至碼云,有興趣的哥們可以參考。
碼云:https://gitee.com/xuzhaoyu/ScreenPixelDemo
場景一:UI拿著一份1334 * 750(參照iPhone 8)的效果圖時,各位Androider心里肯定千萬個草泥馬奔騰,這種分辨率的圖能用?簡直渣渣?。》叛郛?dāng)下安卓陣營,1000-2000價位,遍地2K屏幕,遍地“全面屏”,1334*750這種“類720P”分辨率的蘋果效果圖,安卓百元機(jī)都不好意思用,還要我們做的與其一致?
場景二:在5.0寸的1920 * 1080設(shè)備上,一個Button的寬度為180dp,大概占屏幕寬度1/2??墒窃?.8寸1920 * 1200的某設(shè)備上,該Button寬度居然只占了屏幕的1/4到1/3的樣子,最終UI和產(chǎn)品驗收產(chǎn)品的時候,BBBB,Androider心里同樣千萬個草泥馬。
滿滿痛點啊!現(xiàn)今安卓陣營高分設(shè)備越來越多,屏幕適配刻不容緩,讓我們自己動手,豐衣足食。如果您還不了解px,dp,dpi,請先移步補(bǔ)充px,dp,dpi的概念。
不知道諸位是否使用過鴻洋的AutoLayout,簡直是安卓碎片化大背景下的屏幕適配的救星。不過可惜的是,AutoLayout已經(jīng)停止更新很久,而且本身在兼容性上也存在一定問題,比如僅支持三大布局的如下屬性:
1.layout_width
2.layout_height
3.layout_margin(left,top,right,bottom)
4.pading(left,top,right,bottom)
5.textSize
其次,Autolayout對部分含有虛擬按鍵的機(jī)型適配不佳。
再者,全面屏(18:9)機(jī)型也有很多,如果UI給的基準(zhǔn)分辨率比例為16:9,在全面屏機(jī)型上會出現(xiàn)畫面被拉高的問題。
那么我們該如何做屏幕適配呢?為了更好的兼容性,讓我們回到屏幕適配的起點,看看基本的做法:在項目moudle/src/main/res/包下建立對應(yīng)分辨率包,如values-1920 * 1080,values-1280 * 720等,并在每個包內(nèi)創(chuàng)建合適的dimen,如下圖所示:
當(dāng)設(shè)備的分辨率為1920 * 1080時,就會讀取values-1920 * 1080包下的dimen值,當(dāng)設(shè)備分辨率為1280 * 720時,就會讀取values-1280 * 720包下的dimen值,以此類推。
這種方式的兼容性毫無疑問是最佳的,而且也幾乎不用考慮性能損失。如果采取這種方式進(jìn)行適配,那么接下來的兩個問題是:
1.我們到底有多少種分辨率?也就是要建立多少種values-xxxx*xxxx包?
2.然后又如何給每個包內(nèi)生成dimen值?
一、主流設(shè)備的分辨率
為了保證兼容性,兩行哥公司的App搜集了用戶設(shè)備屏幕尺寸的信息,抓取到的分辨率如下(為期1年左右,近80款):
1440* 2427; 800 * 1217; 1600* 2434; 1024* 720; 1440* 2368; 1440* 2768; 1600* 2461; 1080* 1809; 1080* 2220; 1080* 2076; 1080* 2094; 1080* 1815; 1080* 1919; 1080* 1804; 1080* 2016; 1080* 2030; 720 * 1166; 1920* 1080; 1080* 2160; 720 * 1192; 1280* 720; 800 * 1232; 1080* 2034; 576 * 1024; 621 * 1104; 1080* 1797; 1080* 1803; 1080* 1825; 1080* 1810; 1200* 1920; 800 * 1216; 1200* 1848; 1080* 1848; 1200* 1852; 720 * 1200; 1080* 2040; 720 * 1216; 900 * 1600; 1200* 1830; 1080* 1821; 1152* 1920; 1600* 2560; 1440* 2434; 1600* 2452; 768 * 1184; 768 * 1280; 1536* 2048; 1440* 2792; 936 * 1664; 1080* 1788; 1080* 1794; 1080* 1830; 1080* 1800; 720 * 1208; 320 * 432; 320 * 480; 800 * 1280; 1440* 2416; 1200* 1824; 1080* 1806; 480 * 854; 1200* 1836; 1440* 2560; 1536* 2560; 1440* 2392; 1440* 2408; 1080* 1812; 600 * 976; 720 * 1242; 540 * 960; 1080* 1776; 240 * 320; 480 * 800; 480 * 640; 720 * 1184; 600 * 1024; 1080* 1920; 720 * 1280; 1440 * 2960; 720 * 1440。
那就以此為標(biāo)準(zhǔn),我們根據(jù)上述分辨率建立values-xxxx * xxxx包。
二、生成dimen值
這里借用鴻洋的autolayout.jar工具(具體參見http://blog.csdn.net/lmj623565791/article/details/45460089)。
將圖中標(biāo)注的autolayout.jar拷貝至任意目錄,在當(dāng)前目錄下打開命令窗口。例如,在windows環(huán)境下,在文件管理器中,按住Shift,右鍵,選擇在此處打開命令窗口。在彈出的命令行窗口中,按照如下格式輸入命令:
java -jar autolayout.jar defaultWidth defaultHeight targerWidth1,targetHeight1_targerWidth2,targetHeight2_targerWidth3,targetHeight3......
defaultWidth,defaultHeight就是基準(zhǔn)分辨率,targetWidth和targetHeight就是目標(biāo)分辨率,可以有多個目標(biāo)分辨率。
例如:
UI的效果圖基于1334 * 750(基準(zhǔn)分辨率),上面有一個寬50px,高20px的控件,那么換算到目標(biāo)分辨率(1920 * 1080 和 1280 * 720)上的寬高是多少呢?運行如下命令:
圖3 命令行
運行完畢你會發(fā)現(xiàn)在autolayout.jar所在的路徑下生成了一個res文件夾,拷貝到項目中即可。
請先點進(jìn)去看看res里面有什么,然后再繼續(xù)閱讀。
如果我們想把上述1334 * 750分辨率下效果圖中寬50px,高20px的控件,適配到我們想要的分辨率中怎么辦呢?寫控件時的寬高為x50和x20就可以了(或者寬高為x50和y20,但是不建議,見下文),如下圖:
稍微看一下,1920 * 1080分辨率下,x20 = 28.8px,x50 = 72px(<dimen name="x20">28.8px</dimen>,<dimen name="x50">72.0px</dimen>),即1920 * 1080 分辨率下寬28.8px,高72px與1334 * 750 分辨率下寬20px,高50px所占屏幕比例一致,做到了完美適配。
那么接下來就把兩行哥生成dimen的代碼附上,省的各位手敲麻煩:
java -jar autolayout.jar 750 1334 1600,2434_1600,2461_1600,2560_1600,2452_1536,2048_1536,2560_1440,2960_1440,2427_1440,2368_1440,2768_1440,2434_1440,2792_1440,2416_1440,2560_1440,2392_1440,2408_1200,1920_1200,1848_1200,1852_1200,1830_1200,1824_1200,1836_1152,1920_1080,1809_1080,2220_1080,2340_1080,2076_1080,2094_1080,1815_1080,1919_1080,1804_1080,2016_1080,2030_1080,2160_1080,2034_1080,1797_1080,1803_1080,1825_1080,1810_1080,1848_1080,2040_1080,1821_1080,1788_1080,1794_1080,1830_1080,1800_1080,1806_1080,1812_1080,1776_1080,1920_900,1600_800,1217_800,1232_800,1216_800,1280_768,1184_768,1280_720,1440_720,1166_720,1192_720,1200_720,1216_720,1208_720,1242_720,1184_720,1280_600,976_600,1024_576,1024_540,960_480,854_480,800_480,640_320,432_320,480_240,320
如果UI給的效果圖是基于1920 * 1080的,那么把上述750(defaultWidth) 1334(defaultHeight)改成1080 1920即可,以此類推。然后參照效果圖的標(biāo)注,標(biāo)注多少px,在項目中就使用dimen/x多少 或 dimen/y多少。
如果要保證控件寬高比例,建議不要使用y的值,因為現(xiàn)在18:9的屏幕也出來了,如果效果圖是16:9,那么在18:9的屏幕中,單位y值已經(jīng)變大,可能使控件被拉高而變形(不再是效果圖中的寬高比),寬高都使用x值即可。如果控件不需要考慮寬高比例,只是需要保證寬高所占屏幕的百分比一致,那么寬使用x,高使用y。請各位讀者自行思考琢磨。
三、其他優(yōu)化
考慮一個問題,生成了這么多的values包,我們放入了app這個module。同時,我們項目也依賴了一些第三方的控件庫module,在這些控件module里也有一些xml布局,如果我們想讓它也適配屏幕,該如何做?難道我們在每個第三方控件庫module的src/main/res/都拷貝這么多的values包嗎?其實不用,可以參照Demo中的架構(gòu):
新建一個module,將這些values-xxxx * xxxx拷貝進(jìn)去,然后讓需要使用屏幕適配的module依賴這個module即可,如app module,還有一些第三方控件庫module。那么就可以在你想用的地方盡情使用dimen值了。