去年在幫公司面試安卓開發(fā)的時(shí)候經(jīng)常聽到應(yīng)聘者提到今日頭條App的安卓適配方式,有些應(yīng)試者大致上講了一下它的工作原理,即直接強(qiáng)制修改系統(tǒng)提供的像素密度比(density)來完成適配。
個(gè)人覺得這種適配方式相比較 普通的 dp 和 dimen 適配還是有很大優(yōu)勢(shì)的,之所以很多安卓手機(jī)的展示存在問題,無非就是其手機(jī)的分辨率和density之間的對(duì)應(yīng)關(guān)系不符合下圖的標(biāo)準(zhǔn):

舉個(gè)反面教材,前兩年很多人用過的樂視手機(jī)就是這樣,明明是 1920 * 1080的分辨率,可是系統(tǒng)獲取到的 density 卻小于3(大約是2.6這個(gè)樣子),這個(gè)時(shí)候這部手機(jī)展示任何View和文字肯定都是偏小的,而且dp的值越大,其在通過 density 換算出最終像素值的誤差就越明顯。所以今日頭條通過直接修改系統(tǒng)提供的 density 值來完成屏幕適配的方式,是真正的對(duì)癥下藥。
相比其它適配框架,它對(duì)原有代碼的侵入性也很小,只要提供一個(gè)修改 density 的地方,其它地方該怎么寫還是怎么寫,也無需像dimen一樣寫一堆對(duì)應(yīng)分辨率的文件。但不足之處是,今日頭條的適配框架僅僅針對(duì)設(shè)計(jì)圖寬度為 360dp 的App進(jìn)行了適配,如果要使用這套框架,必須還得手動(dòng)修改代碼,計(jì)算出準(zhǔn)確的 density 值,關(guān)鍵的計(jì)算公式如下:

這樣框架的快速的復(fù)用性就打折了。因此,我們可以借鑒圖一,通過官方提供的手機(jī)分辨率和 density 之間的對(duì)應(yīng)關(guān)系來實(shí)時(shí)獲取當(dāng)前設(shè)備的分辨率,算出一個(gè)基本合理的 density 值,和設(shè)備系統(tǒng)提供的值相比較,如果不相等,直接修改。這樣就可以達(dá)到我們將這套屏幕適配代碼隨意復(fù)用的目的了。以上這段話翻譯成代碼該這么寫:

重點(diǎn)來啦~ 介紹使用方式,同時(shí)提供代碼分享地址(獲取代碼點(diǎn)這里,百度云提取碼:7xrs),首先把我提供的代碼復(fù)制到項(xiàng)目當(dāng)中,其次找到 SunUiUtil 下的 fixLayout 方法,把方法的參數(shù)改成自己項(xiàng)目里面的 BaseActivity ,以上工作完成之后,我們就在項(xiàng)目里面的每一個(gè) BaseActivity 中調(diào)用 onCreate 方法的時(shí)候,調(diào)用 SunUiUtil 下的 fixLayout 方法即可完成屏幕適配。
我一般調(diào)用 fixLayout 的位置都在 setContentView 之前:

這樣你的App就可以完美適配任意的手機(jī)屏幕了,為了對(duì)比明顯,我們直接用逍遙模擬器(PC模擬器的 density 一般都和官方要求的誤差很大)來展示適配前后的對(duì)比圖:
適配前(字體大小和自定義下拉刷新UI已經(jīng)慘不忍睹)

適配后(所有問題完美解決)

在本文最后說兩個(gè)注意事項(xiàng):
1)使用本屏幕適配方式,最好不要在基類復(fù)寫 BaseActivity 的 getResource,更不能去修改其中的 DisplayMetrics ,否則將導(dǎo)致我們?cè)O(shè)置好了的 density 值被重新更新覆蓋,達(dá)不到適配目的,錯(cuò)誤代碼如下圖所示,大家千萬不要這么寫:

2)啟用這套UI適配框架之后,我發(fā)現(xiàn)項(xiàng)目原有的圓形頭像切割出問題了,因此我提供的工具包中多了一個(gè)類:CircularImage,大家用它繪制圓形頭像就木有問題了
最后再附上一個(gè)demo的鏈接,這個(gè)demo里面添加了近期和另一個(gè)大牛交流過后的改進(jìn)代碼,可以更完美地適配更多分辨率的屏幕,demo百度云分享地址:鏈接:https://pan.baidu.com/s/1WkWQWnQCLTdUbBfYzJDhqw? 提取碼:u218
以上,完結(jié)撒花,轉(zhuǎn)載請(qǐng)注明出處~