7. 将界面拆分为多个面板
现在,您的应用可以进入和退出全沉浸空间模式,是时候更好地利用它了。一种很好的方法是,将应用的内容拆分为多个面板以填充空间,并(可选)允许用户根据需要移动和调整这些面板的大小。
将应用嵌入子空间
首先,在 XRFundamentalsApp 可组合项中的 Scaffold 可组合项后面添加一个 Subspace 可组合项。子空间是应用中 3D 空间的一部分,您可以在其中构建 3D 布局(例如添加空间面板)、放置 3D 模型,以及为原本的 2D 内容添加深度。
在非 XR 设备上运行时,Subspace 可组合项的内容永远不会进入组合。在 XR 设备上运行时,只有在应用以全沉浸空间模式运行时,内容才会进入组合。
XRFundamentalsApp.kt
import androidx.xr.compose.spatial.Subspace
...
HelloAndroidXRTheme {
Scaffold(...)
Subspace {
}
}
现在,运行应用:
如果应用包含 Subspace 可组合项,系统只会显示该可组合项的内容。这意味着,当您点击该按钮进入全沉浸空间模式时,系统不会再显示任何内容。为了解决此问题,您将在接下来的几个步骤中添加两个空间面板,一个用于包含主要内容,另一个用于包含次要内容。
为主要内容添加面板
如需在全沉浸空间模式下显示主要内容,请在 Subspace 可组合项中添加 SpatialPanel。
由于这是应用的主要面板,因此您可以在其中添加 Scaffold,以保持顶部应用栏中的控件处于显示状态。
在下一个 Codelab 中,您将了解轨道器,轨道器可用于对应用栏中通常包含的控件(例如导航和特定于上下文的操作)进行空间化处理。
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.SpatialPanel
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.layout.height
import androidx.xr.compose.subspace.layout.width
...
Subspace {
SpatialPanel(
modifier = SubspaceModifier
.width(1024.dp)
.height(800.dp)
) {
Scaffold(
topBar = { XRFundamentalsTopAppBar() }
) { innerPadding ->
Box(Modifier.padding(innerPadding)) {
PrimaryCard(
modifier = Modifier
.padding(16.dp)
.verticalScroll(rememberScrollState())
)
}
}
}
}
默认情况下,SpatialPanel 的大小会根据其所含内容的大小来确定,但也可以通过提供 SubspaceModifier 参数来确定。子空间修饰符类似于修饰符,用于修饰面板等空间布局组件。
由于此空间面板的内容未指定其自身的大小,因此必须提供 SubspaceModifier,以便为面板设置宽度和高度。
为次要内容添加面板
现在,您已经让应用在 Full Space 模式下运行,并使用面板来显示主要内容,接下来可以将次要内容移到自己的面板中了。请注意,在空间面板中使用 Surface。如果没有该 Surface,次要卡片将没有背景,因为空间面板本身是透明的(Scaffold 可组合项在前一步中处理了此问题)。
XRFundamentalsApp.kt
import androidx.compose.material3.Surface
...
Subspace {
SpatialPanel() { ... }
SpatialPanel(
modifier = SubspaceModifier
.width(340.dp)
.height(800.dp)
) {
Surface {
SecondaryCardList(
modifier = Modifier
.padding(16.dp)
.verticalScroll(rememberScrollState())
)
}
}
}
现在,再次运行应用。乍一看,第二个面板似乎没有显示,但实际上它是显示的,只是隐藏在主面板后面。
将面板排成一行
与 2D 内容一样,使用行和列有助于并排排列可组合项,而不会出现重叠。使用面板等空间组件时,您可以使用 SpatialRow、SpatialCurvedRow 和 SpatialColumn 可组合项来实现此目的。
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.SpatialCurvedRow
...
Subspace {
SpatialCurvedRow(
curveRadius = 825.dp
) {
SpatialPanel(...) { ... }
SpatialPanel(...) { ... }
}
}
再次运行应用,您应该会看到面板依次排列成一行。
由于您使用的是 SpatialCurvedRow 可组合项,因此面板会围绕用户弯曲,而非保持在同一平面上(这与使用 SpatialRow 时的情况不同),从而为用户带来更加沉浸式的体验。
使面板可调整大小
为了让用户能够控制应用的外观,您可以使用 ResizePolicy 让面板可调整大小。
默认情况下,可调整大小的面板可以缩小到零或无限扩展,因此您可能需要花时间根据面板将包含的内容设置适当的 minimumSize 和 maximumSize 参数。
如需详细了解 ResizePolicy 支持的所有参数,请参阅参考文档。
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.ResizePolicy
...
SpatialPanel(
resizePolicy = ResizePolicy()
)
使面板可移动
同样,您可以使用 MovePolicy 使面板可移动。
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.MovePolicy
...
SpatialPanel(
dragPolicy = MovePolicy()
)
如需详细了解 MovePolicy 支持的所有参数,请参阅参考文档。