web-to-app 屏幕方向锁定全解析:landscapeMode 与 orientationMode 双字段如何实现竖横屏控制

发布时间:2026/9/29 6:15:32
web-to-app 屏幕方向锁定全解析:landscapeMode 与 orientationMode 双字段如何实现竖横屏控制 web-to-app 屏幕方向锁定全解析landscapeMode 与 orientationMode 双字段如何实现竖横屏控制本文围绕 web-to-app「编辑通用配置」中的屏幕方向卡片展开先完整梳理landscapeMode与orientationMode两个配置字段的取值、默认值与界面交互再结合 WebViewActivity 的运行时映射和 APK 构建链路的写入逻辑讲清方向锁从界面开关到实际生效的完整路径。读完本篇你可以准确选择 7 种方向模式中的任意一种理解 TV 设备上的特殊回退策略以及启动画面/媒体方向与主方向设置的相互独立关系。功能入口与两个核心字段屏幕方向设置在 编辑通用配置 编辑器的屏幕方向卡片中。这个卡片背后实际由两个独立的配置字段驱动定义在数据模型 WebApp.kt 的WebViewConfig中val landscapeMode: Boolean false, // 快速开关是否强制横屏 val orientationMode: OrientationMode OrientationMode.PORTRAIT, // 细粒度七种方向模式横屏模式landscapeModeBoolean默认false一个快速切换开关打开即强制横屏。方向模式orientationMode枚举默认PORTRAIT提供 7 种细粒度控制选项。两者存在联动关系landscapeMode本质上是orientationMode在 PORTRAIT / LANDSCAPE 两个基础值之间的快捷表达。这一点可以从界面组件 CreateAppWebViewCards.kt 的LandscapeModeCard签名看出——它同时接收两个状态参数默认值逻辑就是「开关打开时方向为LANDSCAPE关闭时为PORTRAIT」fun LandscapeModeCard( enabled: Boolean, onEnabledChange: (Boolean) - Unit, orientationMode: OrientationMode if (enabled) OrientationMode.LANDSCAPE else OrientationMode.PORTRAIT, ... )orientationMode 的七种取值OrientationMode枚举定义于 WebApp.kt与文档中的选项一一对应枚举值含义对应ActivityInfo常量运行时映射PORTRAIT竖屏SCREEN_ORIENTATION_PORTRAITTV 设备上回退为UNSPECIFIEDLANDSCAPE横屏SCREEN_ORIENTATION_LANDSCAPEREVERSE_PORTRAIT反向竖屏SCREEN_ORIENTATION_REVERSE_PORTRAITREVERSE_LANDSCAPE反向横屏SCREEN_ORIENTATION_REVERSE_LANDSCAPESENSOR_PORTRAIT传感器竖屏SCREEN_ORIENTATION_SENSOR_PORTRAITSENSOR_LANDSCAPE传感器横屏SCREEN_ORIENTATION_SENSOR_LANDSCAPEAUTO自动SCREEN_ORIENTATION_USER跟随系统旋转设置几点使用语义选择横屏模式开关会相应设置landscapeMode传感器模式SENSOR_*不是绝对锁死而是在「竖屏/横屏」这一约束内跟随设备重力传感器旋转。AUTO映射到SCREEN_ORIENTATION_USER而非SENSOR这一点在源码中有明确注释「USER (not SENSOR) to match ShellScreens AUTO handling」即遵循用户在系统设置里手动选择的旋转策略。界面交互基础模式与高级模式分层在 LandscapeModeCard 的 Compose 实现中卡片分为三层顶部总开关标题为方向模式标签勾选状态等于「当前是否为非 PORTRAIT 的自定义方向」isCustomOrientation orientationMode ! PORTRAIT。打开时直接进入LANDSCAPE关闭时回到PORTRAIT。基础模式区仅展示LANDSCAPE横屏与AUTO自动两个选项各自带描述文案。高级模式区可折叠包含REVERSE_PORTRAIT、REVERSE_LANDSCAPE、SENSOR_PORTRAIT、SENSOR_LANDSCAPE四个选项按「反向方向」「传感器方向」两个小标题分组。一个值得注意的细节是折叠区的自动展开逻辑CreateAppWebViewCards.ktvar advancedExpanded by remember { mutableStateOf( orientationMode in listOf( OrientationMode.REVERSE_PORTRAIT, OrientationMode.REVERSE_LANDSCAPE, OrientationMode.SENSOR_PORTRAIT, OrientationMode.SENSOR_LANDSCAPE ) ) }即如果应用已保存了某个高级方向值编辑卡片会默认展开高级区保证用户能看到当前选中项未使用高级选项时则保持折叠避免界面冗余。此外选中AUTO或SENSOR_*时卡片底部会展示对应的动态提示条orientationAutoHint、orientationSensorPortraitHint等向用户解释「跟随系统旋转」或「约束内跟随传感器」的具体行为。运行时生效WebViewActivity 的方向映射当应用或编辑器内的预览加载时WebViewActivity.kt 会将orientationMode逐值翻译成 Activity 的requestedOrientation。预览模式previewApp分支与已保存应用appId分支使用完全一致的映射核心代码如下when (app.webViewConfig.orientationMode) { OrientationMode.LANDSCAPE - { activity.requestedOrientation ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE } OrientationMode.REVERSE_PORTRAIT - { activity.requestedOrientation ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT } OrientationMode.REVERSE_LANDSCAPE - { activity.requestedOrientation ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE } OrientationMode.SENSOR_PORTRAIT - { activity.requestedOrientation ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT } OrientationMode.SENSOR_LANDSCAPE - { activity.requestedOrientation ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE } OrientationMode.AUTO - { // USER (not SENSOR) to match ShellScreens AUTO handling. activity.requestedOrientation ActivityInfo.SCREEN_ORIENTATION_USER } OrientationMode.PORTRAIT - { if (TvUtils.isTv(context)) { activity.requestedOrientation ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED } else { activity.requestedOrientation ActivityInfo.SCREEN_ORIENTATION_PORTRAIT } } }其中PORTRAIT分支包含一个 TV 兼容回退当 TvUtils 判定当前设备是电视/大屏设备时不锁竖屏而是设为UNSPECIFIED允许系统自由选择方向——这符合电视场景下用户通常期望横屏观看的习惯。构建时固化导出 APK 如何携带方向配置web-to-app 导出的 APK 会把方向设置固化进应用配置构建链路涉及三个文件写入ApkBuilder.kt 在生成配置时同时写出两个字段——landscapeMode landscapeMode布尔与orientationMode orientationMode.name枚举名转字符串构建日志中也会打印landscapeMode的当前值L428便于排查。ApkConfigJsonFactory.kt 同样把orientationMode to webView.orientationMode序列化进配置 JSON。默认值ApkConfig.kt 中orientationMode的缺省值为字符串PORTRAIT保证旧配置或缺字段的应用按竖屏兜底。运行时读取生成的 Shell 应用在 ShellModeManager.kt 中声明了对应字段从内嵌配置 JSON 反序列化SerializedName(landscapeMode) val landscapeMode: Boolean false, SerializedName(orientationMode) val orientationMode: String PORTRAIT,从这条链路可以看出方向设置在导出的 APK 中是构建期写入、运行期读取的修改方向需要重新编辑配置。配置字段的双向序列化还有专门的回归测试保障例如 ConfigRoundTripSentinelTest.kt、WebViewConfigBooleanCoverageTest.kt 与 WebViewConfigDefaultsContractTest.kt覆盖landscapeMode/orientationMode的往返一致性与默认值契约。注意启动画面与媒体有独立的方向设置文档特别指出启动画面和媒体有各自独立的方向设置与主方向设置互不干扰。这一点在源码中得到印证启动画面使用独立枚举 SplashOrientation仅PORTRAIT/LANDSCAPE两值。当splashConfig.orientation LANDSCAPE时WebViewActivity.kt 会在启动画面播放期间临时把方向强改为横屏并先保存originalOrientation以便结束后恢复if (app.splashConfig.orientation SplashOrientation.LANDSCAPE) { originalOrientation activity.requestedOrientation activity.requestedOrientation ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE }媒体应用MediaConfig同样持有orientation: SplashOrientation字段WebApp.kt默认PORTRAITApkBuilder.kt 导出时也分别按splashConfig与mediaConfig独立计算landscape标志。因此即使主方向设置为竖屏你仍然可以让启动画面以横屏呈现两者互不影响。启动画面的完整配置请参阅启动动画文档。实践建议普通网页类应用保持默认PORTRAIT或选择AUTO跟随用户系统设置即可无需干预。视频/游戏类横屏应用打开横屏模式开关等价orientationMode LANDSCAPE这是最常用的快捷路径。需要倒装或传感器自由旋转的桌面/车载场景展开高级区选择REVERSE_*或SENSOR_*从源码结构看传感器模式适合「只限横着拿、但允许两端翻转」这类需求。TV 设备无需担心竖屏锁死问题PORTRAIT模式在 TV 上会自动回退为不限方向。若同时配置了横屏启动画面注意它只在播放期间临时生效退出后恢复为主方向设置。以上所有配置均在 web-to-app 的「编辑通用配置 → 屏幕方向」卡片中完成导出的 APK 会按当前设置固化方向行为。创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考