CameraX beta03 和底部 sheet 滚动问题

CameraX beta03 and bottom sheet scroll issue

我正在将项目中的 cameraX alpha 升级到 1.0.0-beta03。我正在关注 this。一切正常,我能够按预期拍摄图像。

但我在相机片段中有底sheet。在我实现了 beta03 之后,当滚动底部时 sheet,它似乎被一些不可见的视图重叠,像这样:

调试了一段时间后发现只有当我将 camera?.cameraInfo 传递给 viewFinder.createSurfaceProvider 时才会发生这种情况。如果我传递 null,则不会发生此问题。但我不知道这意味着什么。

preview?.setSurfaceProvider(
                viewFinder.createSurfaceProvider(camera?.cameraInfo))

这里传null的时候,底部sheet完全上来了

文档是这么说的:

/**
     * Gets the {@link Preview.SurfaceProvider} to be used with
     * {@link Preview#setSurfaceProvider(Executor, Preview.SurfaceProvider)}.
     * <p>
     * The returned {@link Preview.SurfaceProvider} will provide a preview
     * {@link android.view.Surface} to the camera that's either managed by a
     * {@link android.view.TextureView} or {@link android.view.SurfaceView}. This option is
     * determined by the {@linkplain #setPreferredImplementationMode(ImplementationMode)
     * preferred implementation mode} and the device's capabilities.
     *
     * @param cameraInfo The {@link CameraInfo} of the camera that will use the
     *                   {@link android.view.Surface} provided by the returned
     *                   {@link Preview.SurfaceProvider}.
     * @return A {@link Preview.SurfaceProvider} used to start the camera preview.
     */

我在 google 的示例应用程序中添加了一个随机底部 sheet 并推送它 here(Github link) 并重现了错误。 (请构建Cameraxbasic模块。我的分支是Bug_repro_bottomsheet

有人可以解释一下这是怎么回事以及如何解决这个问题吗?

注意:我尝试更新底部的 z-index 和高程 sheet。它没有用

PreviewView.createSurfaceProvider() 的文档指出:

The returned Preview.SurfaceProvider will provide a preview Surface to the camera that's either managed by a TextureView or SurfaceView. This option is determined by the preferred implementation mode and the device's capabilities.

请注意,预览表面是由 TextureView 还是 SurfaceView 管理,部分取决于您传递给 PreviewView.createSurfcaeProvider()CameraInfo 实例。

  • 如果您传入 nullPreviewView 默认使用 TextureView
  • 如果您传入非空 CameraInfo 实例,PreviewView 将尝试使用 SurfaceView,但会回退到使用 TextureView设备,例如旧版设备、运行 API 24 级或更低级别的设备等

回到你看到的问题,当你传入一个非空的 CameraInfo 实例时,它就会发生,这可能是因为你测试的设备支持 SurfaceView 很好,所以 PreviewView 使用它。

当您拉起底部 sheet 时,它会在 SurfaceView 结束的地方停止。尽管 SurfaceView 似乎占据了整个屏幕,但它只占据了屏幕的一部分(从屏幕顶部到底部 sheet 停止点的矩形),那是因为 SurfaceView 被放大以填满整个屏幕(PreviewView 在内部调用方法 SurfaceView.setScaleX()PSurfaceView.setScaleY(),导致预览拉伸,但 SurfaceView 的边界,也就是它在 View 层次结构中占据的矩形,不会改变)。

通过 SurfaceView 的 documentation,您会看到:

The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed.

SurfaceView 与典型的 View 不同,它 handled/rendered 不同于普通的 View,它的表面存在于单独的层上,独立于用于呈现 View 层次结构的图形层。因此,如果您打算让其他 View 滚动到预览顶部,您可能需要强制 PreviewView 使用 TextureView 来管理预览表面。您可以通过将 null 传递给 PreviewView.createSurfaceProvider() 或调用 PreviewView.setPreferredImplementationMode(ImplementationMode.PreviewView).

来完成此操作

您可以阅读更多关于 PreviewView here

对于 androidx.camera:camera-view:1.0.0-alpha31 只需将兼容 implementationMode 设置为 PreviewView(在 setSurfaceProvider) 解决这个问题:

previewView.implementationMode = PreviewView.ImplementationMode.COMPATIBLE