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

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

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

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

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

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

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

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