天天看點

Android 今日頭條螢幕适配詳細使用攻略前言1. 螢幕像素2. 适配原理3. 架構配置4. 自定義初始化5. 常用方法解析6. 常見接口及類的使用7.架構核心8. 其它總結

Android 第三方庫系列文章

  1. Android 今日頭條螢幕适配詳細使用攻略
  2. Lottie動畫 輕松使用

今日頭條螢幕适配

  • 前言
  • 1. 螢幕像素
  • 2. 适配原理
  • 3. 架構配置
  • 4. 自定義初始化
  • 5. 常用方法解析
  • 6. 常見接口及類的使用
  • 7.架構核心
  • 8. 其它
  • **總結**

部落格建立時間:2020.09.20

部落格更新時間:2021.06.27

以Android studio build=4.2.1,gradle=6.7.1,SdkVersion 30來分析講解。如圖文和網上其他資料不一緻,可能是别的資料版本較低而已

前言

首先感謝大神JessYan的創神之作《AndroidAutoSize》,大神以今日頭條螢幕适配的核心代碼為基礎進行了擴充封裝,産生了《AndroidAutoSize》這個能快速接入使用的螢幕适配方案,這個螢幕适配方案是我遇到的截止2020.9.15為止最強大、簡單有效的螢幕适配方案。我已使用該方案有一年,在使用過程未發現有何問題,強烈推薦各位極客們使用學習。

以下是大神JessYan的相關位址:

  • 郵箱:[email protected]
  • github:https://github.com/JessYanCoding/AndroidAutoSize
  • 簡書:https://www.jianshu.com/p/4aa23d69d481
  • 原始核心代碼:https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA

大神的源碼都在github中各位可以自行下載下傳,我寫這篇部落格的目的就是記錄使用心得,并将該架構的重要類和方法使用進行詳細說明,大神的文章中對細節問題寫的比較少,我對其進行了細微的修改和詳細的注解解釋。我自己修改注釋過得架構源碼請前往github下載下傳https://github.com/l424533553/MyAutoSize。

1. 螢幕像素

像素

通常所說的像素,就是CCD/CMOS上光電感應元件的數量,一個感光元件經過感光,光電信号轉換,A/D轉換等步驟以後,在輸出的照片上就形成一個點,我們如果把影像放大數倍,會發現這些連續色調其實是由許多色彩相近的小方點所組成,這些小方點就是構成影像的最小機關“像素”(Pixel)。簡而言之,像素就是手機螢幕的最小構成單元。

螢幕尺寸

螢幕尺寸指螢幕的對角線的長度,機關是英寸,1英寸=2.54厘米。比如常見的螢幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等

螢幕分辨率

螢幕分辨率是指在橫縱向上的像素點數,機關是px,1px=1個像素點。一般以縱向像素橫向像素,如19201080

螢幕像素密度(dpi)

螢幕像素密度是指每英寸上的像素點數,機關是dpi,即“dot per inch”的縮寫。螢幕像素密度與螢幕尺寸和螢幕分辨率有關,在單一變化條件下,螢幕尺寸越小、分辨率越高,像素密度越大,反之越小。

Android 今日頭條螢幕适配詳細使用攻略前言1. 螢幕像素2. 适配原理3. 架構配置4. 自定義初始化5. 常用方法解析6. 常見接口及類的使用7.架構核心8. 其它總結

計算公式: 像素密度 = 像素 / 尺寸 (dpi = px / in)

标準螢幕像素密度(mdpi): 每英寸長度上還有160個像素點(160dpi),即稱為标準螢幕像素密度(mdpi)。

密度無關像素(dp)

含義:density-independent pixel,叫dp或dip,與終端上的實際實體像素點無關

機關:dp,可以保證在不同螢幕像素密度的裝置上顯示相同的效果,是安卓特有的長度機關。

場景例子:假如同樣都是畫一條長度是螢幕一半的線,如果使用px作為計量機關,那麼在480x800分辨率手機上設定應為240px;在320x480的手機上應設定為160px,二者設定就不同了;如果使用dp為機關,在這兩種分辨率下,160dp都顯示為螢幕一半的長度。

dp與px的轉換:1dp = (dpi / 160 ) * 1px;

密度類型 代表的分辨率(px) 螢幕像素密度(dpi) 換算
低密度(ldpi) 240 x 320 120 1dp = 0.75px
中密度(mdpi) 320 x 480 160 1dp = 1px
高密度(hdpi) 480 x 800 240 1dp = 1.5px
超高密度(xhdpi) 720 x 1280 320 1dp = 2px
超超高密度(xxhdpi) 1080 x 1920 480 1dp = 3px

獨立比例像素(sp)

scale-independent pixel,叫sp或sip,字型大小專用機關 ,Android開發時用此機關設定文字大小,可根據字型大小首選項進行縮放。

推薦使用12sp、14sp、18sp、22sp作為字型大小,不推薦使用奇數和小數,容易造成精度丢失,12sp以下字型太小。

sp與dp的差別

dp隻跟螢幕的像素密度有關, sp和dp很類似但唯一的差別是,Android系統允許使用者自定義文字尺寸大小(小、正常、大、超大等等),當文字尺寸是“正常”時1sp=1dp=0.00625英寸,而當文字尺寸是“大”""或“超大”時,1sp>1dp=0.00625英寸。類似我們在windows裡調整字型尺寸以後的效果——視窗大小不變,隻有文字大小改變。

2. 适配原理

傳統的螢幕适配頭如下幾種措施:

  1. 種像素密度機型,做5套圖。比例 1:1.5:2:3:4
  2. 多用相對布局
  3. 尺寸限定符
  4. 點九圖
  5. 不同圖檔填充類型ScaleType

    但是以往的所有螢幕适配都有各種各樣的問題和重大缺陷,直到位元組跳動的螢幕适配方案出現。根據其公開的核心源碼,網上重大大咖封裝了各種螢幕适配架構,其中最成功且本人使用感受最好的是AutoSize架構。

Android AutoSize的核心代碼來源于位元組跳動的微信文章https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA。網上也有多各個大神進行了代碼的封裝設計,都是萬變不離其中。

1. 核心思想

DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();
        if (sNoncompatDensity == 0) {
            sNoncompatDensity = appDisplayMetrics.density;
            sNoncompatDensity = appDisplayMetrics.scaledDensity;
            application.registerComponentCallbacks(new ComponentCallbacks() {
                
                public void onConfigurationChanged(Configuration newConfig) {
                    if (newConfig != null && newConfig.fontScale > 0) {
                        sNoncompatScaledDensity = application.getResources().getDisplayMetrics().scaledDensity;
                    }
                }

                
                public void onLowMemory() {

                }
            });
        }
        float targetDensity = appDisplayMetrics.widthPixels / 360;
        float targetScaleDensity = targetDensity * (sNoncompatScaledDensity / sNoncompatDensity);
        int targetDensityDpi = (int) (160 * targetDensity);
        appDisplayMetrics.density = targetDensity;
        appDisplayMetrics.scaledDensity = targetScaleDensity;
        appDisplayMetrics.densityDpi = targetDensityDpi;

        final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
        activityDisplayMetrics.density = targetDensity;
        activityDisplayMetrics.scaledDensity = targetScaleDensity;
        activityDisplayMetrics.densityDpi = targetDensityDpi;
           

原理很簡單,例如一個4.59的10801920的手機它的dpi=480,它的density=480/160,則說明1dp=3px。當我們在布局中給如TextView設定layout_width=30dp時,在程式運作時會自動計算其對應px機關長度90px,px=dpdensity。

今日頭條适配方案的核心就是動态計算程式中的density=appDisplayMetrics.widthPixels / 360,360是原始設計圖紙的dp。假設原先的設計圖紙10801920,現在适配5.99寸560dpi的14402880手機,則30dp=30560/160=105px,實際上螢幕适配要求的30dp=1440/36030=120px才可以達到适配效果。因為120/1440=90/1080,控件在布局中的占寬比是一樣的才能達到寬度适配效果。這就是為什麼要動态修改全局或activity的DisplayMetrics#density的目的了。

2. 優缺點

  • 優點:
  1. 侵入性非常低,該方案和項目完全解耦,使用的還是Android官方機關
  2. 接入無性能損耗,使用的全是Android官方的API。
  • 缺點:
  1. 項目中的系統控件、三方庫控件、等非我們項目自身設計的控件,它們的設計圖尺寸并不會和我們項目自身的設計圖尺寸一樣,此時會産生适配誤差。解決方案就是取消目前 Activity 的适配效果,改用其他的适配方案
  2. 系統修改字型大小後,傳回應用系統字型大小還是未改變,需要設定registerComponentCallbacks監聽。 Android AutoSize架構已經解決了該問題。
  3. 在使用過程中需要進行registerComponentCallbacks監聽内容文字的大小改變情況,解決退出應用修改文字大小後,文字大小不改變的情況。

3. 架構配置

依賴配置

  1. 遠端依賴,截止到2020.9.15,版本為1.2.1
  1. 從github上下載下傳源碼進行library庫依賴

參數配置

在AndroidManifest.xml中配置參數

<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>
           

4. 自定義初始化

本文中使用的架構是經過大神JessYan的封裝後成為你所看到的架構。它能根據一套給定的設計圖尺寸進行布局展示,當安裝當不同分辨率尺寸的裝置上時,它能自動适配螢幕。

架構的初始化時機是配置在ContentProvider中,在Application#onCreate()方法之前啟動。架構一旦初始化完成,其适配效果會在Activity和Fragment、各種View中自動全局适配。程式将預設是以螢幕寬度為基準進行适配的,并且使用的是在AndroidManifest中填寫的全局設計圖尺寸進行全局适配。

架構支援dp、sp兩個主機關,pt、in、mm三個冷門副機關,如果使用副機關,可以規避系統控件或三方庫控件使用的不良影響。

ContentProvider初始化第三方庫

ContentProvider是一種共享型元件,它通過Binder向其他元件或者其他應用程式提供資料,當ContentProvider所在程序啟動時候,ContentProvider會被同時啟動并被釋出到AMS中。

ContentProvider的onCreate要優先于Application的onCreate,但在attachBaseContext()之後而執行,它的具體詳細啟動源碼在ActivityThread中。很多人會在ContentProvider#onCreate()初始化第三方庫。

一般進行了依賴配置和參數配置兩操作,Android AutoSize就配置完成可以直接使用了,它的架構源碼初始化在InitProvider代碼中。

在InitProvider 中已進行了初始化設定

public class InitProvider extends ContentProvider {
    @Override
    public boolean onCreate() {
        if (getContext() != null) {
            Context application = getContext().getApplicationContext();
            if (application == null) {
                application = AutoSizeUtils.getApplicationByReflect();
            }
            AutoSizeConfig.getInstance()
                    .setLog(true)
                    .init((Application) application)
                    .setUseDeviceSize(false);
            return true;
        }
        return false;
    }
           

但是為了個性化的配置,我們可以在Application中進行一些自定義設定,設定的方法都應寫在Application#onCreate()方法中。

public class Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ...
        AutoSize.initCompatMultiProcess(this);
        AutoSize.checkAndInit(this);
        AutoSizeConfig.getInstance()
                .setCustomFragment(true)
                .setExcludeFontScale(true)
                .setPrivateFontScale(0.8f)
                .setLog(false)
                .setBaseOnWidth(true)
                .setUseDeviceSize(true)
                //螢幕适配監聽器
                .setOnAdaptListener(new OnAdaptListener() {
                    @Override
                    public void onAdaptBefore(Object target, Activity activity) {
//                        AutoSizeConfig.getInstance().setScreenWidth(ScreenUtils.getScreenSize(activity)[0]);
//                        AutoSizeConfig.getInstance().setScreenHeight(ScreenUtils.getScreenSize(activity)[1]);
                        AutoSizeLog.d(String.format(Locale.ENGLISH, "%s onAdaptBefore!", target.getClass().getName()));
                    }

                    @Override
                    public void onAdaptAfter(Object target, Activity activity) {
                        AutoSizeLog.d(String.format(Locale.ENGLISH, "%s onAdaptAfter!", target.getClass().getName()));
                    }
                });
        configUnits();
    }
    
    private void configUnits() {
        AutoSizeConfig.getInstance()
                .getUnitsManager()
                .setSupportDP(true)
                .setDesignSize(2160, 3840)
                .setSupportSP(true)
                .setSupportSubunits(Subunits.MM);
    }
}
           

5. 常用方法解析

對于初始化中方法,我們進行一一分析

1. AutoSize.initCompatMultiProcess(Context context)

當 App 中出現多程序,并且您需要适配所有的程序,就需要在 App 初始化時調用。一般的單程序App程式不用設定。

2. AutoSize.checkAndInit(Application application)

if (!checkInit()) {
            AutoSizeConfig.getInstance()
                    .setLog(true)
                    .init(application)
                    .setUseDeviceSize(false);
        }
           

一般來說Android AutoSize會通過InitProvider執行個體化自動完成初始化,是不需要調用checkAndInit()方法的。但由于某些 issues 反應, 可能會在某些特殊情況下出現InitProvider未能正常執行個體化的情況, 導緻 AndroidAutoSize 未能完成初始化。是以需要使用該方法確定Android AutoSize 初始化成功。

3. AutoSizeConfig.getInstance().setCustomFragment(boolean customFragment)

設定是否讓架構支援自定義Fragment 的适配參數,一般這個需求比較少。預設不支援的

4. AutoSizeConfig.getInstance().setExcludeFontScale(true)

是否屏蔽系統字型大小對AndroidAutoSize 的影響, 如果為 true, App 内的字型的大小将不會跟随系統設定中字型大小的改變, 如果為 false, 則會跟随系統設定中字型大小的改變, 預設為 false

5. AutoSizeConfig.getInstance().setPrivateFontScale(float fontScale)

差別于系統字型大小的放大比例, AndroidAutoSize 允許 APP 内部可以獨立于系統字型大小之外,獨自擁有全局調節 APP 字型大小的能力。 fontScale取值0~1,設為 0 則取消此功能。同時字型的機關必須是sp做機關。

6. AutoSizeConfig.getInstance().setLog(boolean log)

設定是否列印AutoSize的日志,true為列印

7. AutoSizeConfig.getInstance().setBaseOnWidth(true)

是否全局按照寬度進行等比例适配,true以寬來适配,false以高來适配

8. AutoSizeConfig.getInstance().stop(this)

自動适配方案可以手動調用方法停止,需要注意的是Android AutoSize暫停隻是停止了對後續還沒有啟動的{@link Activity}進行适配的工作,但對已經啟動且已經适配的{@link Activity}不會有任何影響

9. AutoSizeConfig.getInstance().restart()

AutoSize可以暫停适配也可以重新開機适配,但是重新開機适配隻能對後續還沒有啟動的 {@link Activity} 進行适配的工作,但對已經啟動且在stop期間未适配的{@link Activity}不會有任何影響

10. AutoSizeConfig.getInstance().setUseDeviceSize(true)

是否以螢幕的實際尺寸為高度,預設為false,螢幕的适配高度是螢幕總高度減去狀态欄高度。

11. UnitsManager.setSupportSP(boolean supportSP)

是否讓架構支援sp機關,預設是為true支援,如果為false,則字型大小最好設定為其他機關才能自動适配

12. UnitsManager.setSupportSubunits(Subunits supportSubunits)

自主設定心儀的副機關,可以從pt、in、mm中進行選擇,如果使用了Subunits#NONE即代表不支援副機關

13. UnitsManager.setSupportDP(boolean supportDP)

是否支援dp機關,預設是true支援,如果關閉将不對dp機關進行支援

14. UnitsManager.setDesignSize(float designWidth, float designHeight)

設定設計圖尺寸,一般專為副機關尺寸設計,它與AndroidManifest.xml中配置的參數不一樣,不會被覆寫。

6. 常見接口及類的使用

CustomAdapt

實作CustomAdapt接口即可對activity和fragment進行新的自定義尺寸适配,适配方向可以自主選擇是寬度還是高度。實作該接口會取消預設的适配方案和效果。對于fragment的自定義尺寸需要進AutoSizeConfig.getInstance().setCustomFragment(true)設定,預設是不支援對fragment的自定義尺寸适配的。

<在CustomAdapt接口中需要實作者重寫兩個方法boolean isBaseOnWidth()和float getSizeInDp(),根據使用者需求自定義。

  • 1. boolean isBaseOnWidth()

    為了保證在高寬比不同的螢幕上也能正常适配,是以隻能在寬度和高度之中選一個作為基準進行适配。 true為按照寬度适配, false 為按照高度适配

  • 2. float getSizeInDp()

    getSizeInDp 須配合isBaseOnWidth()使用, 有如下使用規則:

    如果 {@link #isBaseOnWidth()} 傳回 {@code true}, {@link CustomAdapt #getSizeInDp} 則應該傳回設計圖的總寬度。

    如果 {@link #isBaseOnWidth()} 傳回 {@code false}, {@link CustomAdapt #getSizeInDp} 則應該傳回設計圖的總高度。

    如果您不需要自定義設計圖上的設計尺寸, 想繼續使用在 AndroidManifest 中填寫的設計圖尺寸,getSizeInDp 則傳回 0即可。

CancelAdapt

接口CancelAdapt沒有任何成員變量,支援AndroidAutoSize的項目所有子產品預設使用适配功能,第三方庫的也不例外。

如果某個頁面不想使用适配功能, 請讓該頁面實作CancelAdapt接口放棄适配,所有的适配效果都将失效。

7.架構核心

1. 自定義适配

通過位元組跳動的核心源碼,隻能進行全局适配,但是該架構中進行了Activity和Fragmen的自定義适配和随時取消恢複适配功能。它的原理是注冊了ActivityLifecycleCallbacks,進行了Activity的适配時間精準化自我掌控。

通過注冊ActivityLifecycleCallbacks,進行Activity的生命周期進行管理, 當onActivityCreated時,也就是OnCreate()的setContentView之前進行了AutoAdaptStrategy#applyAdapt的調用。這種方案類似于 AOP, 面向接口, 侵入性低, 友善統一管理, 擴充性強。

@Override
    public void onActivityCreated(@androidx.annotation.NonNull Activity activity, Bundle savedInstanceState) {
        if (AutoSizeConfig.getInstance().isCustomFragment()) {
            if (mFragmentLifecycleCallbacksToAndroidx != null && activity instanceof androidx.fragment.app.FragmentActivity) {
                ((androidx.fragment.app.FragmentActivity) activity).getSupportFragmentManager().registerFragmentLifecycleCallbacks(mFragmentLifecycleCallbacksToAndroidx, true);
            }
        }
        //Activity 中的 setContentView(View) 一定要在 super.onCreate(Bundle); 之後執行
        if (mAutoAdaptStrategy != null) {
            mAutoAdaptStrategy.applyAdapt(activity, activity);
        }
    }
           

通過注冊registerFragmentLifecycleCallbacks,進行Fragment的生命周期管理,當onFragmentCreated時,也就是OnCreate()中進行了AutoAdaptStrategy#applyAdapt的調用

@Override
public void onFragmentCreated(@androidx.annotation.NonNull FragmentManager fm, @androidx.annotation.NonNull Fragment f, Bundle savedInstanceState) {
        if (mAutoAdaptStrategy != null) {
            mAutoAdaptStrategy.applyAdapt(f, f.getActivity());
        }
    }

           

通過全局的進行Activity和Fragment的生命周期監控,在其布局建立之前調用 AutoAdaptStrategy#applyAdapt進行具體的适配操作,它的關鍵點是動态修改density、scaledDensity、densityDpi三個參數,造成每個Activity或Fragment加載布局時的density、scaledDensity、densityDpi等參數不一樣,達到的适配效果則不一樣。

2. 适配政策的實作

ActivityLifecycleCallbacks的使用能實時監測Activity和Fragment進行适配調用,但是實際操作的代碼在政策方案AutoAdaptStrategy的實作子類中,架構中已有預設政策方案,當然自己也可以自定義修改建立。

  • 當target實作CancelAdapt後,将density、scaledDensity、densityDpi恢複到原始狀态,不進行比對
  • 當target實作CustomAdapt後,将density、scaledDensity、densityDpi根據target的配置進行計算後設定
  • 當target未進行任何處理時,将density、scaledDensity、densityDpi根據AndroidManifest.xml中的配置進行計算設定
@Override
    public void applyAdapt(Object target, Activity activity) {
    	....
        //如果 target 實作 CancelAdapt 接口表示放棄适配, 所有的适配效果都将失效
        if (target instanceof CancelAdapt) {
            AutoSizeLog.w(String.format(Locale.ENGLISH, "%s canceled the adaptation!", target.getClass().getName()));
            AutoSize.cancelAdapt(activity);
            return;
        }

        //如果 target 實作 CustomAdapt 接口表示該 target 想自定義一些用于适配的參數, 進而改變最終的适配效果
        if (target instanceof CustomAdapt) {
            AutoSizeLog.d(String.format(Locale.ENGLISH, "%s implemented by %s!", target.getClass().getName(), CustomAdapt.class.getName()));
            AutoSize.autoConvertDensityOfCustomAdapt(activity, (CustomAdapt) target);
        } else {
            AutoSizeLog.d(String.format(Locale.ENGLISH, "%s used the global configuration.", target.getClass().getName()));
            AutoSize.autoConvertDensityOfGlobal(activity);
        }
        ...
    }
   
           

8. 其它

1. Fragment橫豎屏切換布局問題

由于某些原因, 螢幕旋轉後 Fragment 的重建, 會導緻架構對 Fragment 的自定義适配參數失去效果。是以如果您的 Fragment 允許螢幕旋轉, 則請在 onCreateView 手動調用一次 AutoSize.autoConvertDensity(),如AutoSize.autoConvertDensity(getActivity(), 1080, true)。

如果您的 Fragment 不允許螢幕旋轉, 則可以将下面調用 AutoSize.autoConvertDensity() 的代碼删除掉

public class CustomFragment1 extends Fragment implements CustomAdapt {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //由于某些原因, 螢幕旋轉後 Fragment 的重建, 會導緻架構對 Fragment 的自定義适配參數失去效果
        //是以如果您的 Fragment 允許螢幕旋轉, 則請在 onCreateView 手動調用一次 AutoSize.autoConvertDensity()
        //如果您的 Fragment 不允許螢幕旋轉, 則可以将下面調用 AutoSize.autoConvertDensity() 的代碼删除掉
        AutoSize.autoConvertDensity(getActivity(), 1080, true);
        return createTextView(inflater, "Fragment-1\nView width = 360dp\nTotal width = 1080dp", 0xffff0000);
    }
           

2. 主副機關的逐漸替換

架構中同時支援主機關和副機關,對于對于舊項目中已使用dp或px的項目,可以通過逐漸在新頁面中使用主機關副機關。通過不斷的疊代替換,最終将項目中的主機關如dp全替換為副機關px,或者将副機關px全替換為主機關dp。

當機關都替換完成後,設定UnitsManager.setSupportDP(false)關閉對dp的支援,徹底隔離修改 density 所造成的不良影響。

或者都使用dp,不在支援副機關時設定UnitsManager.setSupportSubunits(Subunits.NONE)關閉對副機關的支援。

3. 主副機關的同時支援

當使用者想将舊項目從主機關過渡到副機關, 或從副機關過渡到主機關時。因為在使用主機關時, 建議在 AndroidManifest 中填寫設計圖的 dp 尺寸, 比如 360 * 640。

但在 AndroidManifest 中卻隻能填寫一套設計圖尺寸, 并且已經填寫了主機關的設計圖尺寸,是以當項目中同時存在副機關和主機關, 并且副機關的設計圖尺寸與主機關的設計圖尺寸不同時, 可以通過UnitsManager#setDesignSize() 方法配置。

如果副機關的設計圖尺寸與主機關的設計圖尺寸相同, 則不需要調用 UnitsManager#setDesignSize(), 架構會自動使用 AndroidManifest 中填寫的設計圖尺寸。

4. 自定義機關模拟器建立

布局時的實時預覽在開發階段是一個很重要的環節, 很多情況下 Android Studio 提供的預設預覽裝置并不能完全展示我們的設計圖。是以我們就需要自己建立模拟裝置, 大神@JessYan已經為我們準備好了dp、pt、in、mm 這四種機關的模拟裝置建立方法,請點選檢視連結https://github.com/JessYanCoding/AndroidAutoSize/blob/master/README-zh.md#preview

總結

經過我自己修改注釋的源碼在https://github.com/l424533553/MyAutoSize中,大家也可以自行封裝架構,适合自己的才是最好的。

螢幕自适應的核心就是根據需要在使用之前不斷修改density、scaledDensity、densityDpi達到适配效果。

相關連結:

  1. Android 今日頭條螢幕适配詳細使用攻略
  2. Lottie動畫 輕松使用

擴充連結:

  1. Android CameraX 使用入門
  2. Android studio 最全必用插件
  3. Android 史上最新最全的ADB及指令百科,沒有之一

部落格書寫不易,您的點贊收藏是我前進的動力,千萬别忘記點贊、 收藏 ^ _ ^ !