4. 预览目标旋转角处理
为什么预览方向会“歪”
CameraX 的 Preview 默认会依据设备自然方向(natural orientation)和传感器方向自动计算旋转,但当你把界面锁定为竖屏、或 Activity 被系统重建、或使用自定义 PreviewView 容器时,自动结果可能与用户看到的画面方向不一致。此时需要显式设置 Preview.targetRotation,把“显示方向”的期望值告诉 CameraX。
关键概念:targetRotation 不是“旋转多少度”,而是“期望的显示方向”,取值来自 Surface.ROTATION_0 / 90 / 180 / 270,CameraX 会结合传感器方向换算出实际旋转量。
配置 targetRotation 的两种策略
策略一:跟随系统显示方向。适用于大多数普通预览场景,让预览始终与用户手持方向一致。
// 在绑定 Preview 之前或之后均可设置
val preview = Preview.Builder().build()
preview.targetRotation = display.rotation // display 来自 Activity 的 windowManager
// 若使用 PreviewView,也可通过其 display 获取
previewView.display?.let { preview.targetRotation = it.rotation }
策略二:固定方向。适用于界面锁定竖屏、或需要预览始终以某个方向呈现的场景。
// 强制预览始终为竖屏方向
preview.targetRotation = Surface.ROTATION_0
在 Activity 方向变化时同步更新
当 Activity 因旋转被重建时,display.rotation 会变化,需要在重建后重新赋值。若使用 android:configChanges 避免重建,则需在 onConfigurationChanged 中手动更新。
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
val rotation = display.rotation
preview.targetRotation = rotation
}
若使用 CameraX 的
CameraController(PreviewView 的简化封装),它内部已自动处理 targetRotation,无需手动设置。本案例针对直接使用 Preview UseCase 的场景。验证旋转后的显示效果
- 启动应用,确认竖屏下预览画面中的人像/景物方向正常,无 90° 歪斜。
- 将设备顺时针旋转 90° 进入横屏,观察预览画面是否随之旋转并保持正确方向。
- 若 Activity 被重建,检查重建后预览是否仍然方向正确;若未重建,检查
onConfigurationChanged是否生效。 - 将设备倒置(180°),确认预览方向是否跟随;若固定为
ROTATION_0,则画面应保持竖屏方向不变。
常见问题:设置
targetRotation 后画面仍歪斜,通常是因为 PreviewView 的 scaleType 或父容器布局导致裁剪,而非旋转角错误。可先确认 targetRotation 是否与 display.rotation 一致,再排查布局。快速检查表
| 检查项 | 预期 | 异常处理 |
|---|---|---|
| 竖屏下预览方向 | 人像正立 | 检查 targetRotation 是否为 ROTATION_0 |
| 横屏旋转后 | 画面跟随旋转 | 确认 display.rotation 已更新并重新赋值 |
| Activity 重建后 | 方向保持正确 | 在 onCreate 中重新设置 targetRotation |
| 固定方向场景 | 画面不随设备旋转 | 确认 targetRotation 未被其他代码覆盖 |