向应用添加子空间

子空间是应用内 3D 空间的一个分区,您可以在其中放置 3D 模型、构建 3D 布局,并为原本为 2D 的内容添加深度。只有在启用空间化时,系统才会渲染子空间。在主空间或非 XR 设备上,系统会忽略该子空间中的所有代码。

您可以使用 @SubspaceComposable(例如 VolumeSpatialPanel)来放置 3D 模型。某些 XR 组件(例如 OrbiterSpatialDialog)是标准的 2D 可组合项,可在 2D 界面层次结构中的任何位置使用,但 SubspaceComposable 必须在应用的子空间中调用。为此,您将使用 Subspace 可组合项。

与任何其他可组合项一样,您可以在二维界面层次结构中直接调用 Subspace。不过,请务必了解在层次结构中的哪个位置调用 Subspace 会产生什么影响。

子空间层次结构简介

顶级子空间是应用调用的最外层子空间。此子空间实际上具有无限边界,通常是放置应用的空间布局和 SpatialPanel 的位置。

不过,如果您在顶级子空间中包含的面板中嵌套另一个子空间,则该嵌套子空间的行为会有所不同。

嵌套子空间与顶级 Subspace 有两个主要区别:

  • 它们会参与调用它们的 2D 布局。这意味着子空间的高度和宽度将受其 2D 父布局的高度和宽度约束。
  • 它们的行为方式与它们在其中被调用的实体的子项相同。这意味着,如果您调用嵌套在 SpatialPanel 中的 Subspace 可组合项,该子空间将是其被调用的 SpatialPanel 的子项。

嵌套子空间的这些行为支持以下功能:

  • 随父实体一起移动子实体
  • 使用偏移量 SubspaceModifier 偏移子项的位置
  • 呈现悬停在 2D 界面上方且与 2D 布局中相应空间的高度和宽度相匹配的 3D 对象

向应用添加子空间

以下代码示例展示了如何向应用添加顶级子空间和嵌套子空间。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    enableEdgeToEdge()
    setContent {
        // This is a top-level subspace
        Subspace {
            SpatialPanel {
                MyComposable()
            }
        }
    }
}
@Composable
private fun MyComposable() {
    Row {
        PrimaryPane()
        SecondaryPane()
    }
}
@Composable
private fun PrimaryPane() {
      ...
    // This is a nested subspace, because PrimaryPane is in a SpatialPanel
    // and that SpatialPanel is in a top-level Subspace
    Subspace {
        ObjectInAVolume(show3DObject)
    }
      ...
}