android中一種方便的適配方案

android設備衆多,這致使適配各類機型很麻煩,其中屏幕適配也是一件棘手的事情。其中一種方式是在res文件夾下,根據不一樣的屏幕分辨率創建一一對應的values文件夾,以下圖所示: java

其實這種適配方式也能夠知足適配要求,使用起來中規中矩的感受。今天我想介紹另一種適配方案,那就是github.com/JessYanCodi…android

使用姿式

  • 添加依賴

implementation 'me.jessyan:autosize:1.1.2'git

  • manifest文件中添加以下配置
<manifest>
    <application>            
        <meta-data android:name="design_width_in_dp" android:value="360"/>
        <meta-data android:name="design_height_in_dp" android:value="640"/>           
     </application>           
</manifest>
複製代碼
  • 界面適配
public class CustomAdaptActivity extends AppCompatActivity implements CustomAdapt {

    @Override
    public boolean isBaseOnWidth() {
        return false;
    }

    @Override
    public float getSizeInDp() {
        return 667;
    }
}
複製代碼

若是某個特殊的activity不須要適配,則實現CancelAdapt接口github

public class CancelAdaptActivity extends AppCompatActivity implements CancelAdapt {

}
複製代碼

fragment的適配跟activity如出一轍,都是實現CustomAdapt接口進行適配,實現CancelAdapt接口告訴框架不須要適配.markdown

  • 使用過程當中遇到的問題
  1. 在接入第三方庫的時候,第三方的activity和fragment也要進行適配,否則就會報以下錯誤

「java.lang.RuntimeException: Unable to start activity ComponentInfo{com.wdg.tradecenter/com.yanzhenjie.permission.PermissionActivity}:java.lang.IllegalArgumentException: you must set design_width_in_dp in your AndroidManifest file」app

能夠在Application#onCreate方法中添加以下代碼取消對指定的activity和fragment取消適配檢查框架

AutoSizeConfig.getInstance()
                .getExternalAdaptManager()
                .addCancelAdaptOfActivity(PermissionActivity.class);
複製代碼
  • 應用

上圖是lanhu上的一張ui設計圖,咱們點擊控件,右下角直接就出現了對應的xml代碼,使用autosize進行適配,就能夠直接使用lanhu上生成的佈局代碼,這一點確實方便了一些。ide

框架原理

  • 單位
單位 解釋
px 像素
dp 獨立設備像素 計算公式:px = dp(dpi/160)
dpi 像素密度,指的是在系統軟件上指定的單位尺寸的像素數量,它每每是寫在系統出廠配置文件的一個固定值

經過上面的單位介紹及之間的轉換,咱們能夠獲得以下結論:oop

px= dp(dpi/160), density = dpi/160 => px = dp*density => dp = px/density; 明白上面這個結論,下面咱們來討論爲何咱們平常對控件設置的寬/高爲某一dp時,沒法作到各個手機屏幕的適配。佈局

設備 A , 屏幕寬度爲 720px, dpi爲160,則屏幕總dp爲 720/(160/160) = 720 dp 設備 B , 屏幕寬度爲 720px, dpi爲320,則屏幕總dp爲 720/(320/160) = 360 dp 能夠看到屏幕的總 dp 寬度在不一樣的設備上是會變化的,可是咱們在佈局中填寫的 dp 值倒是固定不變的,這就致使咱們設置的固定寬度在不一樣的設備上顯示的比例不同。 例如咱們佈局中有一個View設置固定寬度爲180dp,在設備A中會佔屏幕寬度的1/4,可是在設備B中只會佔屏幕寬度的1/2,這種差異是十分巨大的。

這時咱們要想完美適配,那就必須保證這個 View 在任何分辨率的屏幕上,與屏幕的比例都是相同的。

解決方案

由公式:dp = px/density 可知,因爲px是屏幕分辨率,這個值有硬件肯定,咱們是沒法改變的,那麼咱們能夠經過修改density 的值使得不一樣分辨率的手機寬度dp值是相同的,這樣當咱們對View設置爲某一特定的dp寬度時,佔總寬度的dp比例是相同的,這樣也就達到佔屏幕的比例相同。

那麼問題來了,咱們如何肯定density 的值呢?

由dp = px/density => 屏幕的總 px 寬度 / density = 屏幕的總 dp 寬度

屏幕的總 px 寬度 / density = 屏幕的總 dp 寬度 => 當前設備屏幕總寬度(單位爲像素)/ 設計圖總寬度(單位爲 dp) = density

若是咱們將一套設計圖的總寬度(dp)做爲最終手機屏幕的中寬度(dp), 從而達到修改density的目的,同時又能夠保證最終不一樣分辨率手機的屏幕總寬度是相同的,這也就完成了適配。

AndroidAutoSize/今日頭條 就是基於這個原理來實現屏幕適配的。

AndroidAutoSize是怎麼以最小侵入代價應用上述原理的

利用ContentProvider初始化該庫—— ContentProvideronCreate的調用時機介於ApplicationattachBaseContextonCreate之間。

在初始化的時候註冊了一個Application.ActivityLifecycleCallbacks接口類回調

application.registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks); 在接口Application.ActivityLifecycleCallbacks的實現類中修改density,以達到適配目的。

總結 這個適配方案優勢明顯

使用成本低,簡單。 代碼侵入性低 沒有性能損耗 可適配activity/fragment/dialog/toast等 缺點

既然AndroidAutoSize庫能夠修改density,其它庫也能夠修改,那麼這樣就會致使衝突。

相關文章
相關標籤/搜索