资讯动态

AndroidAutoSize 屏幕适配方案实战指南:基于今日头条思路的一步式全局适配、副单位与实时预览

发布时间:2026/10/14 20:46:27 来源:尧图企业网站定制
移动开发【免费下载链接】AndroidAutoSize A low-cost Android screen adaptation solution (今日头条屏幕适配方案终极版一个极低成本的 Android 屏幕适配方案).项目地址https://gitcode.com/gh_mirrors/an/AndroidAutoSize点击查看免费下载本篇技术指南围绕 AndroidAutoSize今日头条屏幕适配方案的“终极版”实现展开系统讲解其极低成本的接入方式、底层适配原理、Android Studio 实时预览设备的创建方法以及 Activity / Fragment 自定义适配与 pt、in、mm 副单位等进阶能力。读完本文你将能够为任意 Android 项目在几分钟内接入全局屏幕适配并在源码级理解 density 换算机制的前提下按需定制单页适配参数与单位体系。一、方案概述为什么说它是“极低成本”的屏幕适配方案AndroidAutoSize 的核心思路继承自今日头条官方适配方案通过动态修改DisplayMetrics中的density、scaledDensity、densityDpi等值让设备屏幕的宽度或高度恰好等于设计图的总宽度或总高度从而让布局在所有设备上按同一比例缩放。项目本身只要在AndroidManifest.xml中声明一套全局设计图尺寸框架即可对项目中的所有页面完成适配无需为每个页面写适配代码、无需生成多套 dimens 资源这正是“极低成本”的由来。与原始方案相比AndroidAutoSize 在 AutoSize.java 中额外扩展了对DisplayMetrics#xdpi的改写从而支持pt、in、mm三种冷门单位作为“副单位”同时具备全局/单页自定义参数、Fragment 适配、三方库 Activity 适配、热插拔运行中动态停止/重启等能力。README-zh.md 中展示的 Pixel 2 XL、Pixel XL、Nexus 5X、Nexus 4、Nexus S 等多款不同分辨率、不同 dpi 设备的适配效果截图均验证了该方案在不同屏幕上的等比例缩放一致性。需要说明的是任何屏幕适配方案都无法做到绝对完美方案在“成本与收益”之间做出的取舍是——以宽度或高度为单一基准做等比例缩放这是 AndroidAutoSize 的底层设计选择也是理解其全部配置项的出发点。二、依赖引入JCenter 已停止维护推荐使用 JitPack2.1 JCenter 方式已停止维护README-zh.md 明确指出JCenter 远程仓库自2022 年 2 月 1 日起将无法使用因此下述坐标仅作历史参考不建议新项目使用implementation me.jessyan:autosize:1.2.12.2 JitPack 方式当前推荐Step 1在项目根目录的build.gradle中于allprojects.repositories末尾追加 JitPack 仓库allprojects { repositories { ... maven { url https://jitpack.io } } }Step 2在模块的dependencies中添加依赖dependencies { implementation com.github.JessYanCoding:AndroidAutoSize:v1.2.1 }当前仓库中autosize库的发布脚本位于 autosize/bintray.gradle示例工程见 demo、demo-androidxAndroidX 版本与 demo-subunits副单位专例。README 徽章信息显示其最低支持 Android 4.0API 14及以上版本。三、全局适配真的只需要这一步在AndroidManifest.xml的application节点中填写**全局设计图尺寸单位 dp**即可框架会自动对项目中的所有页面进行适配manifest application meta-data android:namedesign_width_in_dp android:value360/ meta-data android:namedesign_height_in_dp android:value640/ /application /manifest3.1 这两个 MetaData 是如何被读取的从源码看AutoSizeConfig.java 中的getMetaData()会异步开线程通过PackageManager读取design_width_in_dp与design_height_in_dp两个 key。同时init()方法AutoSizeConfig.java会先设置一组默认值兜底未开启副单位时默认设计图尺寸为360 x 640dp开启副单位后默认设计图尺寸为1080 x 1920px。源码注释建议在低配设备上如果担心 MetaData 读取过慢导致适配时取不到设计图尺寸可以主动在Application#onCreate()中调用AutoSizeConfig.getInstance().setDesignWidthInDp(...)/setDesignHeightInDp(...)代替 Manifest 配置方式两方法见 AutoSizeConfig.java。3.2 自动初始化与多进程场景自动初始化框架在库自身的 AndroidManifest.xml 中声明了InitProviderauthorities 为${applicationId}.autosize-init-providermultiprocesstrueInitProvider.java 在onCreate()中自动完成init()因此开发者无需手动初始化。异常兜底若某些特殊场景下InitProvider未能实例化可调用AutoSize.checkAndInit(application)AutoSize.java完成初始化demo 的 BaseApplication.java 中有示例。多进程当 App 出现多进程且希望所有进程都适配时需在Application#onCreate()调用AutoSize.initCompatMultiProcess(context)AutoSize.javademo 中跳转到三方库进程内DefaultErrorActivity的场景就依赖此方法见 BaseApplication.java。四、底层原理density 换算与一次完整的适配调用链4.1 核心换算逻辑以宽度为基准时核心计算位于 AutoSize.java 的autoConvertDensity()方法targetDensity AutoSizeConfig.getInstance().getScreenWidth() * 1.0f / sizeInDp; // 以宽度为基准即以“设备屏幕宽度px÷ 设计图宽度dp”得到目标density使整个屏幕宽度恰好等于设计图的 dp 宽度其余派生值同步计算targetScaledDensity targetDensity * systemFontScalesystemFontScale由初始scaledDensity / density得出保证字体与系统字体大小联动若设置setExcludeFontScale(true)则屏蔽系统字体影响targetDensityDpi (int)(targetDensity * 160)targetScreenWidthDp / targetScreenHeightDp同步写入Configuration让screenWidthDp/screenHeightDp与新的 density 保持一致targetXdpi用于支撑副单位换算见第六节。计算过程中以sizeInDp subunitsDesignSize screenSize等值生成缓存 key结果存入SparseArrayDisplayMetricsInfo避免同一参数组合重复计算AutoSize.java。4.2 赋值动作与 MIUI 兼容setDensity()AutoSize.java会同时改写Activity 的Resources#getDisplayMetrics()与Application 的Resources#getDisplayMetrics()并针对 MIUI 通过反射Resources的mTmpMetrics字段做兼容处理见 AutoSizeConfig.java 与 AutoSize.java以解决 MIUI 7 Android 5.1.1 等机型上适配失效的问题。是否改写各字段由UnitsManager的开关决定主单位 dp/sp 与副单位的开关逻辑见第六节。4.3 类似 AOP 的自动适配调用链框架通过在 ActivityLifecycleCallbacksImpl.java 中注册Application.ActivityLifecycleCallbacks在onActivityCreated/onActivityStarted阶段自动调用适配策略从而免去在 BaseActivity 中手写适配代码且天然支持三方库 Activity。调用链如下Application#registerActivityLifecycleCallbacks在AutoSizeConfig#init中完成ActivityLifecycleCallbacksImpl#onActivityCreated→ 若开启 Fragment 自定义参数则注册FragmentLifecycleCallbacks调用AutoAdaptStrategy#applyAdapt(activity, activity)默认实现为 DefaultAutoAdaptStrategy.java其判定优先级为外部三方库取消适配 外部三方库自定义参数 页面实现CancelAdapt 页面实现CustomAdapt 使用全局配置若设置了监听器WrapperAutoAdaptStrategy.java 会在策略执行前后回调onAdaptListener#onAdaptBefore/onAdaptAfter。从源码结构看开发者也可以通过AutoSizeConfig#setAutoAdaptStrategy()替换整个适配策略类实现完全自定义的适配逻辑。五、Android Studio 布局实时预览dp、pt、in、mm 四种模拟设备创建布局时的实时预览对开发效率影响很大而 Android Studio 的默认预览设备往往不能完整展示设计图因此需要自己创建模拟设备。AndroidAutoSize 默认支持以dp、sp为单位布局主单位同时可通过副单位开关使用pt、in、mm见第六节。不同单位对应的模拟设备“屏幕尺寸”计算公式如下布局单位模拟设备屏幕尺寸计算公式只需填写屏幕尺寸与分辨率开启方式dp(sqrt(纵向分辨率^2 横向分辨率^2)) / dpi默认支持pt(sqrt(纵向分辨率^2 横向分辨率^2)) / 72setSupportSubunits(Subunits.PT)insqrt(纵向分辨率^2 横向分辨率^2)setSupportSubunits(Subunits.IN)mm(sqrt(纵向分辨率^2 横向分辨率^2)) / 25.4setSupportSubunits(Subunits.MM)各公式的换算依据可从 AutoSize.java 的副单位赋值逻辑反推pt每英寸 72 个、mm每英寸 25.4 个而in即以英寸为 1 个单位。如果希望预览时不显示状态栏和导航栏让纵向分辨率刚好填充整个预览页面、显示效果与设计图完全一致可在 Preview 面板中选择panel 主题模拟设备的完整创建步骤参考下图只需填写屏幕尺寸与分辨率两项以 dp 为单位布局时按公式求出屏幕尺寸后创建模拟设备的参数填写示例如下六、进阶用法一Activity 自定义适配与放弃适配6.1 自定义设计图尺寸实现CustomAdapt当某个 Activity 的设计图尺寸与 Manifest 中填写的全局设计图尺寸不同时让该 Activity 实现 CustomAdapt.java 接口即可扩展适配参数public class CustomAdaptActivity extends AppCompatActivity implements CustomAdapt { Override public boolean isBaseOnWidth() { return false; } Override public float getSizeInDp() { return 667; } }接口契约详见 CustomAdapt.java 的注释isBaseOnWidth()返回true以宽度为基准等比例缩放返回false以高度为基准为保证在不同高宽比屏幕上不变形只能在宽、高中二选一作为基准getSizeInDp()配合isBaseOnWidth()使用——以宽为基准时应返回设计图总宽度以高为基准时应返回设计图总高度若返回0则继续使用 Manifest 中填写的全局设计图尺寸此兜底逻辑见 AutoSize.java。demo 中的 CustomAdaptActivity.java 就是一个完整案例全局以宽度为基准、设计图 360 x 640dp而该页面改为以高度为基准并按 iPhone 设计图750px x 1334px高度换算为1334 / 2 667dp返回667。6.2 放弃适配实现CancelAdapt若某个 Activity 想完全放弃适配所有适配效果失效实现空接口 CancelAdapt.java 即可public class CancelAdaptActivity extends AppCompatActivity implements CancelAdapt { }DefaultAutoAdaptStrategy会优先检测页面是否实现CancelAdapt命中则调用AutoSize.cancelAdapt(activity)AutoSize.java将 density、scaledDensity、densityDpi、xdpi 与 screenWidthDp/screenHeightDp 全部恢复为系统初始值。七、进阶用法二Fragment 自定义适配Fragment 自定义参数属于相对少见的需求因此框架默认不开启需要手动打开开关AutoSizeConfig.getInstance().setCustomFragment(true);开启后Fragment 与 Activity 的使用方式完全一致public class CustomAdaptFragment extends Fragment implements CustomAdapt { Override public boolean isBaseOnWidth() { return false; } Override public float getSizeInDp() { return 667; } }public class CancelAdaptFragment extends Fragment implements CancelAdapt { }从源码看Fragment 适配通过FragmentManager.FragmentLifecycleCallbacks实现FragmentLifecycleCallbacksImpl.java 在onFragmentCreated阶段调用applyAdapt(f, f.getActivity())同时框架会依据工程依赖自动选择 AndroidX 版本FragmentLifecycleCallbacksImplToAndroidx.java或 support 版本FragmentLifecycleCallbacksImpl.java判定逻辑见 AutoSizeConfig.java。demo 中的 FragmentHost.java 同时展示了宿主 Activity设计图 720dp 宽与三个自定义 Fragment 的组合用法CustomFragment1.java 还给出了一个重要的实战经验屏幕旋转导致 Fragment 重建后框架对 Fragment 的自定义参数可能失效若页面允许旋转应在onCreateView中手动调用一次AutoSize.autoConvertDensity(getActivity(), 1080, true)。八、进阶用法三副单位Subunits——彻底规避修改 density 的副作用8.1 为什么要使用副单位dp、sp在系统控件与三方库控件中极其常见修改DisplayMetrics#density会影响所有以 dp 布局的控件。为规避这一副作用框架在 UnitsManager.java 中定义了“两个主单位 一个副单位”的体系主单位dp、sp默认开启副单位pt、in、mm三选一枚举定义见 Subunits.java默认关闭Subunits.NONE。副单位本质上是改写DisplayMetrics#xdpi而不是 density由于pt、in、mm在系统控件和三方库中几乎不被使用因此对系统控件与三方库控件零影响。使用副单位后还可以直接在 AndroidManifest 中填写设计图的像素尺寸如 1080 x 1920无需再把像素换算成 dp。8.2 副单位配置示例在Application#onCreate()中完成单位配置AutoSizeConfig.getInstance().getUnitsManager() .setSupportDP(false) .setSupportSP(false) .setSupportSubunits(Subunits.MM);完整的实战示例位于 demo-subunits/BaseApplication.java关闭dp支持、保持sp开启注释说明开启 sp 对三方库影响不大可自行斟酌、选择mm作为副单位对应的 demo-subunits/AndroidManifest.xml 中直接填写了像素尺寸1080 x 1920。8.3 渐进式迁移与setDesignSize从源码注释UnitsManager.java可以推断dp与副单位可以同时开启这是为兼容旧项目而设计旧页面继续用 dp 布局新页面用副单位布局实现渐进式切换全部切换完成后再setSupportDP(false)彻底隔离 density 修改的影响。注意AndroidManifest 只能填写一套设计图尺寸若主单位与副单位的设计图尺寸不同例如主单位 360x640dp、副单位 1080x1920px则需要通过UnitsManager#setDesignSize(designWidth, designHeight)UnitsManager.java单独配置副单位的设计图尺寸尺寸一致时则无需调用。九、更多全局配置项与三方库适配源码补充README 之外AutoSizeConfig.java 还提供了一批可链式调用的全局配置demo 的 BaseApplication.java 中有带注释的完整示例常用项如下配置方法作用说明setBaseOnWidth(boolean)是否全局以宽度为基准等比例适配默认truefalse则全局以高度为基准setUseDeviceSize(boolean)是否使用设备实际尺寸含状态栏适配。默认false即屏幕高度减去状态栏高度全面屏/刘海屏获取到的屏幕高度可能已不含状态栏可设为truesetLog(boolean)是否打印内部日志默认truesetExcludeFontScale(boolean)是否屏蔽系统字体大小对适配的影响默认falsesetPrivateFontScale(float)让 App 独立于系统字体全局调节自身字体大小需以 sp 布局设为 0 则取消setOnAdaptListener(onAdaptListener)适配前/后的监听回调可用于横竖屏切换、分屏缩放等场景下重算屏幕尺寸setAutoAdaptStrategy(AutoAdaptStrategy)替换默认适配策略类stop(activity)/restart()热插拔运行中动态停止 / 重新启动适配功能getExternalAdaptManager()管理三方库 Activity 的适配见下其中setUseDeviceSize的效果可从源码确认AutoSizeConfig.java 的getScreenHeight()在isUseDeviceSize为false时会减去状态栏高度框架默认通过ScreenUtils#getStatusBarHeight()获取状态栏高度也支持setStatusBarHeight(int)手动指定ScreenUtils.java。对于通过远程依赖引入、无法修改源码的三方库 ActivityExternalAdaptManager.java 提供了两种管理方式addCancelAdaptOfActivity(Class)让指定三方库 Activity 放弃适配addExternalAdaptInfoOfActivity(Class, ExternalAdaptInfo)为指定三方库 Activity 提供自定义适配参数ExternalAdaptInfo同样包含基准方向与设计图尺寸见 ExternalAdaptInfo.java。demo 在 BaseApplication.java 中为三方库崩溃页DefaultErrorActivity配置了new ExternalAdaptInfo(true, 400)作为示例。前提是三方库页面使用 dp/sp 布局若其布局全部使用 px则任何 density 方案都无法干预。十、老项目迁移与常见注意事项结合 README-zh.md 的 Notice 说明与仓库示例整理以下几点实践建议AndroidAutoLayout 老项目迁移AndroidAutoSize 可以与 AndroidAutoLayout 共存AndroidAutoLayout 使用 px 布局不受 density 修改影响若老项目部分页面此前用 dp 布局且已受适配影响可让这些旧 Activity 实现CancelAdapt取消适配并建议逐步使用副单位——使用副单位不会影响此前使用 dp 的页面也不会影响三方库与系统控件具体可参考 demo-subunits。设计图尺寸的单位使用主单位dp/sp时Manifest 中填写设计图的 dp 尺寸如 360 x 640使用副单位时可直接填写像素尺寸如 1080 x 1920无需换算。以宽还是以高为基准为保证在不同高宽比屏幕上不变形只能二选一。全局默认以宽为基准个别页面可通过CustomAdapt#isBaseOnWidth()单独切换。Fragment 旋转重建允许旋转的 Fragment 需在onCreateView中手动调用一次AutoSize.autoConvertDensity()见 CustomFragment1.java。多进程与异常初始化多进程场景调用AutoSize.initCompatMultiProcess(context)InitProvider异常时调用AutoSize.checkAndInit(application)。结语AndroidAutoSize 用“一套 Manifest 设计图尺寸 运行时改写 DisplayMetrics”的方式把 Android 屏幕适配的接入成本压缩到了极致同时通过主单位/副单位体系、CustomAdapt/CancelAdapt 接口、Fragment 与三方库支持将今日头条适配方案的灵活性推向了新的高度。本文档对应的仓库中还包含 demo、demo-androidx、demo-subunits 三套可直接运行的示例工程以及注释详尽的 autosize 库源码可作为继续深入学习和二次开发的参考。本项目基于 Apache License 2.0 开源见 LICENSE使用或二次分发时请遵守相应许可条款。赞分享移动开发【免费下载链接】AndroidAutoSize A low-cost Android screen adaptation solution (今日头条屏幕适配方案终极版一个极低成本的 Android 屏幕适配方案).项目地址https://gitcode.com/gh_mirrors/an/AndroidAutoSize点击查看免费下载相关推荐vim-nerdtree-tabs核心功能详解告别标签页混乱的5个技巧vim nerdtree tabs核心功能详解告别标签页混乱的5个技巧 vim nerdtree tabs是一款专为Vim用户设计的高效插件它将NERDTrOpenSora-STDiT-v1-HQ-16x512x512 vs 传统视频生成模型为什么它能成为内容创作者的新宠OpenSora STDiT v1 HQ 16x512x512 vs 传统视频生成模型为什么它能成为内容创作者的新宠 在当今AI视频生成技术飞速发展的时代终极Android屏幕适配指南今日头条方案一键搞定所有设备终极Android屏幕适配指南今日头条方案一键搞定所有设备 还在为Android设备碎片化而烦恼吗 面对市场上成千上万种不同尺寸、不同分辨率的Andro移动开发上一篇ESP芯片固件烧录架构深度解析esptool核心原理与实战部署指南下一篇Sunshine游戏串流终极指南15分钟打造你的个人云游戏平台创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑