Android:在方向更改时保留相机预览,而其他视图可以旋转

Posted

技术标签:

【中文标题】Android:在方向更改时保留相机预览,而其他视图可以旋转【英文标题】:Android: retaining camera preview on orientation change while other views can rotate 【发布时间】:2016-06-21 04:48:36 【问题描述】:

我正在尝试构建自定义相机应用。我有一个扩展 SurfaceView 以进行相机预览的类。当设备改变方向时,该表面会被破坏并重新创建,从而导致明显的“故障”,从而降低用户体验。

我想做的是防止在方向更改时必须重新创建此相机预览。此外,我想要一些按钮覆盖这个预览(例如闪光灯,选择前/后摄像头等),这些按钮会在方向改变时旋转。这类似于股票相机应用程序所做的:

Stock camera in landscape mode.

Stock camera in portrait mode. Note that buttons rotate on orientation change.

我发现的最佳方法(例如,here)是使用清单文件强制活动方向为横向,并在拍摄照片后根据实际设备方向旋转生成的图片。据我了解,这种方法的缺点是这也会阻止重叠按钮的旋转。或者,当我阅读了一些关于使用片段和保留片段实例的内容时,我想知道是否可以通过保留包含相机预览的片段来实现我的目标(是的,我是菜鸟)。

这样做的正确方法是什么?

【问题讨论】:

【参考方案1】:

如果您的清单未声明活动处理方向更改,并且未锁定到单个方向,则设备的旋转将导致整个活动被卸载并再次重新加载。这不就是你现在所经历的吗?

如果您为您的活动指定android:configChanges="orientation|screenSize",那么用户体验将会更加流畅。但是,在这种旋转之后,您仍然无法保持相机预览“完整”;布局将被重建。

最后,股票相机应用程序的方法是设置固定(通常是横向)活动方向,并通过更改按钮和其他 UI 元素来伪造纵向方向。但是如果你在底部寻找系统通知或导航(软)按钮,你会明白实际上设备被锁定在横向,只有控件被重绘。您还会注意到相机应用程序避免使用标准文本小部件,因为此类小部件无法轻松旋转。

顺便说一句,你的问题还有一个误解。如果要将图片存储为纵向,则无论您的活动方向如何,都需要(或不需要)手动旋转 JPEG。在大多数设备上,相机只能生成横向 JPEG 文件。 Camera API 包含setRotation() 方法,但通常这只在JPEG 标头中设置一个EXIF 标志。并非所有图像查看器都尊重此标志。如果您不想妥协,您可能需要手动旋转图像。

【讨论】:

谢谢。您说股票相机应用程序“通过更改按钮和其他 UI 元素来伪造纵向”,他们是如何做到的?我猜他们在清单中为此活动设置了android:screenOrientation="landscape",但是如何旋转 UI 元素呢? 他们有一个OrientationListener,当他们检测到设备已经变成纵向时,他们会旋转按钮图标。您可以在开源股票 Camera app 和 Open camera 中找到它 带有监听器的普通相机似乎是最好的方法。但是,是否有任何可用的解决方案来使用 OrientationListener 旋转状态栏(通知、电池等)? 我刚刚找到了this answer 的方法。使用方向监听器和configChanges 选项,我可以在没有默认旋转动画的情况下重新组织视图。我在onLayout 中设置了正确的位置并调用invalidate。无论如何,谢谢;) @nitrico 也许这些问题会帮助你找到你需要的东西:How to create a BottomBar as StickyBottomCaptureLayout in camera2 Android api? 和 Redraw multiple Paths at same positions from previous layout orientation

以上是关于Android:在方向更改时保留相机预览,而其他视图可以旋转的主要内容,如果未能解决你的问题,请参考以下文章

Android:编码的相机预览帧总是横向的。如何旋转?

由于相机预览而产生 OutOfMemoryError

在 android 中设置显示方向后,相机相机预览不正确

如何在android studio中修复CameraSource预览方向

如何确定相机预览帧的默认方向?

如何在android中制作圆形的相机预览?