ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Android 13 Launcher3深度定制实战:打造16宫格默认文件夹的终极指南

Android 13 Launcher3深度定制实战:打造16宫格默认文件夹的终极指南 一、引言为什么需要自定义 Launcher3 文件夹在 Android 系统开发中原生的 Launcher3 桌面启动器往往无法满足企业定制、教育平板、车载系统或智能家居等场景的特殊需求。默认的 3x3 或 4x3 文件夹布局在信息展示效率和空间利用上都不够理想。本文将基于 Android 13 源码中的 Launcher3 模块从架构分析到代码实践系统讲解如何将默认文件夹改造为 16 宫格4x4布局。全文超过 20000 字涵盖 Workspace、CellLayout、FolderPagedView、DeviceProfile、DragController 等核心组件的深入剖析让你掌握 Launcher3 任意布局定制的通用方法。阅读完成后你将具备以下能力独立分析 Launcher3 源码结构、修改 DeviceProfile 实现全局网格定制、在 FolderPagedView 中动态控制文件夹行列数、处理动画性能与适配问题以及完整编译部署修改后的桌面 APK。二、Android 13 Launcher3 架构全景图2.1 模块划分Android 13 的 Launcher3 源码位于packages/apps/Launcher3核心子包职责如下src/com/android/launcher3/入口 ActivityLauncher.java、工作区Workspace、拖拽控制器DragController、全局状态LauncherAppState等。src/com/android/launcher3/model/数据模型层负责加载应用列表、Widget 信息、持久化布局。src/com/android/launcher3/dragndrop/拖拽放置逻辑处理图标拖入文件夹、跨页拖动等。src/com/android/launcher3/folder/文件夹功能模块包含 Folder.java、FolderIcon.java、FolderPagedView.java 等是本文焦点。src/com/android/launcher3/graphics/图标阴影、文件夹背景绘制。src/com/android/launcher3/util/工具类。src/com/android/launcher3/config/配置常量和 FeatureFlags。res/布局文件、尺寸值、样式和图片资源。2.2 核心概念Workspace用户可左右滑动的主屏幕工作区每个页面是一个 CellLayout。Workspace 继承自 PagedView负责页面切换和弹性滚动。CellLayout网格布局容器通过 mCountX列数和 mCountY行数定义图标排列密度。每个图标通过 cellX、cellY、spanX、spanY 占据网格位置。Hotseat屏幕底部固定停靠栏也是一个 CellLayout不受页面切换影响。Folder将图标拖拽到一起时创建的文件夹浮层内部包含 FolderPagedView 进行内容展示和翻页。DeviceProfile设备适配配置文件根据屏幕尺寸、DPI 等计算所有 UI 元素的尺寸和行列数。修改它是全局改变布局的最直接方式。2.3 文件夹的 View 层级文件夹打开后在 DragLayer 上构建如下层级DragLayer全屏覆盖└── Folder容器FrameLayout 子类├── FolderIcon桌面图标预览├── FolderNameEditText名称编辑框└── FolderPagedView翻页网格容器└── CellLayout x N每页一个网格布局改造的核心就在于 FolderPagedView 内 CellLayout 的行列数配置。三、环境搭建与源码准备3.1 硬件和软件要求操作系统Ubuntu 20.04 / 22.04 或 macOS内存16 GB 以上磁盘至少 250 GB 空闲空间Android Studio Hedgehog 或更新版本测试设备Pixel 系列或原生 Android 13 设备可解锁 Bootloader3.2 下载 Android 13 源码使用 repo 工具下载指定分支的 AOSP 源码例如 android-13.0.0_r43# 安装 repo mkdir ~/bin export PATH~/bin:$PATH curl https://storage.googleapis.com/git-repo-downloads/repo ~/bin/repo chmod ax ~/bin/repo 初始化并同步 mkdir aosp13 cd aosp13 repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r43 repo sync -j8Launcher3 源码位置为packages/apps/Launcher3。3.3 单独编译 Launcher3source build/envsetup.sh lunch aosp_arm64-userdebug mmm packages/apps/Launcher3 # 查找 APK 文件 find out/ -name Launcher3*apk -type f通过adb install -r推送到设备即可测试。3.4 导入 Android Studio在 AOSP 根目录执行make idegen development/tools/idegen/idegen.sh用 Android Studio 打开生成的android.ipr等待索引完成定位到 Launcher3 模块四、文件夹核心源码深度剖析4.1 Folder.javaFolder.java 是文件夹功能的核心类关键成员mContentFolderPagedView 实例承载文件夹内所有页面和图标。mInfoFolderInfo 数据对象包含文件夹 ID、标题、应用列表。mFolderIcon桌面的 FolderIcon 视图。mState当前状态STATE_NONE / STATE_SMALL / STATE_ANIMATING / STATE_OPEN。关键方法bind(FolderInfo)负责绑定数据并初始化 FolderPagedViewanimateOpen()和animateClosed()控制展开/关闭动画arrangeChildren()重排内部图标。4.2 FolderPagedView.javaFolderPagedView 继承自 PagedView是实现文件夹内多页滑动的关键。构造时从 DeviceProfile 获取 mGridCountX、mGridCountY并动态创建 CellLayout 页面。bindItems()方法根据每页容纳数countX * countY将快捷方式逐个分配到不同页面和网格位置。// 简化的 bindItems 逻辑 int itemsPerPage mGridCountX * mGridCountY; for (int i 0; i items.size(); i) { int page i / itemsPerPage; int indexInPage i % itemsPerPage; int cellX indexInPage % mGridCountX; int cellY indexInPage / mGridCountX; // 添加到对应 CellLayout }修改 mGridCountX/Y 为 4 即可实现每页 16 个图标。4.3 CellLayout.javaCellLayout 是网格布局容器关键属性mCountX、mCountY、mCellWidth、mCellHeight、mWidthGap、mHeightGap。通过setGridSize(x, y)设置行列数内部会重新计算单元格尺寸并更新子 View 的 LayoutParams。4.4 DeviceProfile.javaDeviceProfile 集中管理所有 UI 元素的尺寸和位置。文件夹相关字段public int folderGridCountX; // 文件夹列数 public int folderGridCountY; // 文件夹行数 public int folderIconSizePx; // 图标尺寸 public int folderCellWidthPx; // 单元格宽度 public int folderCellHeightPx; // 单元格高度这些值在构造或updateFromConfiguration()时根据屏幕参数动态计算。五、config.xml 与多 DPI 配置5.1 关键 XML 配置项res/values/config.xml中与文件夹相关的配置integer nameconfig_folderGridCountX3/integer integer nameconfig_folderGridCountY3/integer integer nameconfig_folderMaxPages3/integer这些默认值在运行时可能被 DeviceProfile 覆盖因此修改后仍需要检查 Java 侧的计算。5.2 多 DPI 资源覆盖Launcher3 使用values-sw600dp、values-sw720dp、values-sw840dp等目录适配不同尺寸设备。为确保在所有设备上生效需要同步修改这些目录下的 config.xml 中的 folderGridCountX/Y。六、16 宫格定制方案一修改 DeviceProfile推荐6.1 思路在 DeviceProfile 构造函数或工厂方法中将 folderGridCountX 和 folderGridCountY 均设置为 4并同步重新计算单元格尺寸和图标大小。6.2 具体修改// DeviceProfile.java private DeviceProfile(Context context, InvariantDeviceProfile inv, ...) { // ... 前置计算 ... // 设置为 4x4 16宫格 folderGridCountX 4; folderGridCountY 4; // 重新计算单元格尺寸 int availableWidth folderContentWidth - 2 * folderCellPadding; int availableHeight folderContentHeight - 2 * folderCellPadding; folderCellWidthPx availableWidth / folderGridCountX; folderCellHeightPx availableHeight / folderGridCountY; // 图标尺寸约为单元格的 70% folderIconSizePx (int) (Math.min(folderCellWidthPx, folderCellHeightPx) * 0.7f); }同时要调整文件夹整体宽度、间距等参数确保在窄屏手机上也能显示 4 列图标。6.3 文件夹尺寸调整将folderWidth设置为屏幕宽度的 85%~92%为边缘留出点击关闭空间。pageIndicator 高度等也需要微调。七、16 宫格定制方案二直接在 FolderPagedView 中设定7.1 适用场景当你不希望影响全局 DeviceProfile或者需要根据实验分组、用户设置动态切换布局时可以直接在 FolderPagedView 中覆写行列数。7.2 修改 FolderPagedView.java// FolderPagedView.java public FolderPagedView(Context context, AttributeSet attrs) { super(context, attrs); // 直接指定 4x4 mGridCountX 4; mGridCountY 4; // 仍然从 DeviceProfile 获取尺寸、间距等 DeviceProfile dp mActivityContext.getDeviceProfile(); mCellWidth dp.folderCellWidthPx; mCellHeight dp.folderCellHeightPx; // ... setFixedSize(mGridCountX, mGridCountY); }在addNewPage()中也要确保新创建的 CellLayout 使用 4x4 设置。八、FolderIcon 预览图适配8.1 预览图机制FolderIcon 在桌面上显示 2x2 共 4 个应用预览图。16 宫格文件夹的预览图仍建议保持 2x2因为桌面图标较小16 个预览图将无法辨认。8.2 关键代码在 FolderIcon.java 的drawPreviewItems()中通过 PREVIEW_GRID_SIZE 控制排布通常保持 2 不变。如果确实想放大预览可调整 ITEMS_PREVIEW 和预览尺寸但需谨慎。8.3 背景比例微调检查 FolderIcon 背景圆角矩形的尺寸必要时调整folderIconPreviewPadding。九、动画与性能优化9.1 展开动画适配文件夹的animateOpen()使用属性动画建议确保withLayer()开启硬件加速层避免每帧重绘全部子 View。9.2 减少过度绘制对 CellLayout 设置setClipChildren(true)和setClipToPadding(true)文件夹背景选择合适的颜色以遮挡下层内容。9.3 翻页流畅性当文件夹内应用数量超过 16 个时会使用第二页。PagedView 默认不预加载邻页如果内容过多可考虑调整setPageSpacing()和预加载策略。十、完整的代码修改 Checklist步骤文件修改内容1res/values/config.xmlconfig_folderGridCountX/Y 改为 42res/values-sw600dp/config.xml同步改为 43res/values-sw720dp/config.xml同步改为 44res/values-sw840dp/config.xml同步改为 45DeviceProfile.java设置 folderGridCountX/Y4重算尺寸6FolderPagedView.java可选确认构造函数和新增页使用 4x47Folder.java检查 arrangeChildren() 是否依赖旧行列十一、编译与部署source build/envsetup.sh lunch aosp_arm64-userdebug make clean-Launcher3 mmm packages/apps/Launcher3 -j8部署时需注意签名冲突# 停用 Pixel Launcher如果存在 adb shell pm disable-user com.google.android.apps.nexuslauncher # 安装自制 Launcher3 adb install -r out/target/product/generic_arm64/system/product/priv-app/Launcher3/Launcher3.apk adb reboot也可通过 Magisk 模块或直接推送到 /system 的方式实现系统级替换。十二、功能验证与测试用例12.1 测试用例ID场景预期TC-01创建文件夹并拖入 1 个应用第一页显示 1 个图标TC-02拖入第 2-16 个应用按 4x4 排列无重叠TC-03拖入第 17 个应用自动创建第二页TC-04打开含 20 个应用的文件夹第一页 16 个滑动至第二页显示剩余 4 个TC-05滑动切页流畅指示器正确TC-06从文件夹拖出应用剩余应用自动重排TC-07删除最后 1 个应用文件夹自动解散TC-08旋转屏幕4x4 布局自适应12.2 兼容性测试Android 13 原生设备Pixel 4a/5/6/7不同屏幕尺寸5.0~6.8 英寸、折叠屏多种 DPImdpi ~ xxxhdpi分屏模式十三、常见问题与排查13.1 图标重叠原因folderCellWidthPx/HeightPx 计算不正确。确保单元格宽度 (内容区宽度 - 总水平间距) / folderGridCountX。13.2 点击文件夹崩溃通过adb logcat | grep AndroidRuntime查看堆栈常见 NullPointerExceptionDeviceProfile 未初始化或 ArrayIndexOutOfBoundsException页面索引错误。13.3 横竖屏切换布局错乱在 FolderPagedView 中监听配置变化并recreateAllPages()。十四、进阶优化自适应 16 宫格14.1 按屏幕宽度动态调整if (screenWidthDp 360) { folderGridCountX 4; folderGridCountY 4; // 16宫格 } else if (screenWidthDp 320) { folderGridCountX 3; folderGridCountY 4; // 12宫格 } else { folderGridCountX 3; folderGridCountY 3; // 9宫格 }14.2 用户设置切换使用 SharedPreferences 存储偏好在 FolderPagedView 构造时读取并应用监听变化后通知已打开的文件夹重新 bind。十五、代码实战完整 diff 示例AOSP android-13.0.0_r4315.1 DeviceProfile.java folderGridCountX 4; folderGridCountY 4; folderCellWidthPx (folderContentWidth - (folderGridCountX - 1) * folderCellGapX) / folderGridCountX;15.2 FolderPagedView.java if (mGridCountX ! 4 || mGridCountY ! 4) { mGridCountX 4; mGridCountY 4; }15.3 config.xml- integer nameconfig_folderGridCountX3/integer integer nameconfig_folderGridCountX4/integer十六、Launcher3 其它定制场景拓展16.1 从文件夹定制到全桌面定制掌握行列数修改方法后你可以定制桌面网格、Hotseat 图标数量、文件夹样式、Widget 支持等。原理相通定位 DeviceProfile 或对应 View 的网格配置修改数值即可。16.2 跨版本差异本文方法在 Android 12~14 上基本通用14 增加了预测性返回等新特性但不影响网格系统。只需注意字段名可能的微调。十七、调试技巧与工具17.1 Layout Inspector通过 Android Studio 的 Layout Inspector 实时查看文件夹 View 树和尺寸。17.2 adb 命令adb shell pm clear com.android.launcher3 adb shell wm size adb shell am force-stop com.android.launcher317.3 日志调试在关键位置添加日志通过adb logcat -s Folder16Debug:D过滤查看参数传递。十八、总结与最佳实践理解 DeviceProfile → FolderPagedView → CellLayout 的数据流。推荐方案一一处修改全局生效。不要遗漏多 DPI 配置文件。确保动画开启硬件加速层。覆盖创建、拖拽、翻页、旋转、多设备等测试维度。完整掌握本文内容后你将能自信地应对任何 Launcher3 定制需求。祝你在系统桌面优化的道路上越走越顺交付高质量的产品。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进