Với Jetpack Compose cho XR, bạn có thể tạo giao diện người dùng không gian và bố cục theo cách khai báo bằng các khái niệm quen thuộc của Compose như hàng và cột. Điều này cho phép bạn mở rộng giao diện người dùng Android hiện có vào không gian 3D hoặc tạo các ứng dụng 3D sống động hoàn toàn mới.
Nếu đang tạo không gian cho một ứng dụng hiện có dựa trên Khung hiển thị Android, bạn có một số tuỳ chọn phát triển. Bạn có thể sử dụng các API có khả năng tương tác, sử dụng Compose và Khung hiển thị cùng nhau hoặc làm việc trực tiếp với thư viện SceneCore. Hãy xem hướng dẫn về cách làm việc với thành phần hiển thị để biết thêm thông tin chi tiết.
Giới thiệu về không gian con và thành phần không gian
Khi viết ứng dụng cho Android XR, bạn cần hiểu rõ các khái niệm về không gian con và thành phần không gian.
Giới thiệu về không gian con
Khi phát triển cho Android XR, bạn cần thêm một không gian con vào ứng dụng hoặc bố cục. Không gian con là một phân vùng của không gian 3D trong ứng dụng, nơi bạn có thể đặt nội dung 3D, tạo bố cục 3D và thêm chiều sâu vào nội dung 2D. Không gian con chỉ được kết xuất khi bạn bật tính năng không gian. Trong Không gian nhà hoặc trên các thiết bị không phải XR, mọi mã trong không gian con đó sẽ bị bỏ qua.
Có hai cách để tạo không gian con:
setSubspaceContent()
: Hàm này tạo một không gian con cấp ứng dụng. Bạn có thể gọi phương thức này trong hoạt động chính theo cách tương tự như khi sử dụngsetContent()
. Không gian con cấp ứng dụng không giới hạn về chiều cao, chiều rộng và chiều sâu, về cơ bản cung cấp một canvas vô hạn cho nội dung không gian.Subspace
: Bạn có thể đặt thành phần kết hợp này ở bất kỳ vị trí nào trong hệ phân cấp giao diện người dùng của ứng dụng, cho phép bạn duy trì bố cục cho giao diện người dùng 2D và không gian mà không làm mất ngữ cảnh giữa các tệp. Điều này giúp bạn dễ dàng chia sẻ các thành phần như cấu trúc ứng dụng hiện có giữa XR và các hệ số hình dạng khác mà không cần chuyển trạng thái lên trên toàn bộ cây giao diện người dùng hoặc thiết kế lại ứng dụng.
Để biết thêm thông tin, hãy xem phần Thêm không gian con vào ứng dụng.
Giới thiệu về thành phần không gian
Thành phần kết hợp không gian con: Các thành phần này chỉ có thể hiển thị trong không gian con.
Các thành phần này phải được bao bọc trong Subspace
hoặc setSubspaceContent
trước khi được đặt trong bố cục 2D. SubspaceModifier
cho phép bạn thêm các thuộc tính như chiều sâu, độ lệch và vị trí vào các thành phần kết hợp không gian con.
Các thành phần không gian khác không yêu cầu được gọi bên trong không gian con. Các lớp này bao gồm các phần tử 2D thông thường được gói trong một vùng chứa không gian. Bạn có thể sử dụng các phần tử này trong bố cục 2D hoặc 3D nếu xác định cho cả hai. Khi bạn không bật tính năng không gian, các tính năng không gian của chúng sẽ bị bỏ qua và chúng sẽ quay lại các đối tác 2D.
Tạo bảng điều khiển không gian
SpatialPanel
là một thành phần kết hợp không gian con cho phép bạn hiển thị nội dung ứng dụng. Ví dụ: bạn có thể hiển thị chế độ phát video, hình ảnh tĩnh hoặc bất kỳ nội dung nào khác trong bảng điều khiển không gian.
Bạn có thể sử dụng SubspaceModifier
để thay đổi kích thước, hành vi và vị trí của bảng điều khiển không gian, như trong ví dụ sau.
Subspace {
SpatialPanel(
SubspaceModifier
.height(824.dp)
.width(1400.dp)
.movable()
.resizable()
) {
SpatialPanelContent()
}
}
// 2D content placed within the spatial panel
@Composable
fun SpatialPanelContent(){
Box(
Modifier
.background(color = Color.Black)
.height(500.dp)
.width(500.dp),
contentAlignment = Alignment.Center
) {
Text(
text = "Spatial Panel",
color = Color.White,
fontSize = 25.sp
)
}
}
Các điểm chính về mã
- Vì các API
SpatialPanel
là các thành phần kết hợp không gian con, nên bạn phải gọi các API đó bên trongSubspace
hoặcsetSubspaceContent
. Việc gọi các phương thức này bên ngoài một không gian con sẽ gửi một ngoại lệ. - Cho phép người dùng đổi kích thước hoặc di chuyển bảng điều khiển bằng cách thêm đối tượng sửa đổi
movable
hoặcresizable
. - Hãy xem hướng dẫn thiết kế bảng điều khiển không gian để biết thông tin chi tiết về cách định cỡ và định vị. Hãy xem tài liệu tham khảo của chúng tôi để biết thêm thông tin chi tiết về cách triển khai mã.
Tạo vệ tinh nhân tạo
Tàu bay quỹ đạo là một thành phần giao diện người dùng không gian. Thành phần này được thiết kế để đính kèm vào một bảng điều khiển không gian, bố cục hoặc thực thể khác tương ứng. Một vệ tinh nhân tạo thường chứa các mục thao tác theo bối cảnh và điều hướng liên quan đến thực thể mà vệ tinh nhân tạo đó liên kết. Ví dụ: nếu đã tạo một bảng điều khiển không gian để hiển thị nội dung video, bạn có thể thêm các nút điều khiển phát video bên trong một vệ tinh nhân tạo.
Như trong ví dụ sau, hãy gọi một vệ tinh nhân tạo bên trong bố cục 2D trong SpatialPanel
để gói các thành phần điều khiển của người dùng như điều hướng. Thao tác này sẽ trích xuất các thành phần đó từ bố cục 2D và đính kèm vào bảng điều khiển không gian theo cấu hình của bạn.
setContent {
Subspace {
SpatialPanel(
SubspaceModifier
.height(824.dp)
.width(1400.dp)
.movable()
.resizable()
) {
SpatialPanelContent()
OrbiterExample()
}
}
}
//2D content inside Orbiter
@Composable
fun OrbiterExample() {
Orbiter(
position = OrbiterEdge.Bottom,
offset = 96.dp,
alignment = Alignment.CenterHorizontally
) {
Surface(Modifier.clip(CircleShape)) {
Row(
Modifier
.background(color = Color.Black)
.height(100.dp)
.width(600.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "Orbiter",
color = Color.White,
fontSize = 50.sp
)
}
}
}
}
Các điểm chính về mã
- Vì vệ tinh bay vòng quanh là các thành phần giao diện người dùng không gian, nên bạn có thể sử dụng lại mã này trong bố cục 2D hoặc 3D. Trong bố cục 2D, ứng dụng của bạn chỉ hiển thị nội dung bên trong مدار và bỏ qua chính vệ tinh.
- Hãy xem hướng dẫn thiết kế của chúng tôi để biết thêm thông tin về cách sử dụng và thiết kế vệ tinh bay vòng quanh.
Thêm nhiều bảng điều khiển không gian vào bố cục không gian
Bạn có thể tạo nhiều bảng điều khiển không gian và đặt các bảng điều khiển đó trong một bố cục không gian bằng cách sử dụng SpatialRow
, SpatialColumn
, SpatialBox
và SpatialLayoutSpacer
.
Mã ví dụ sau đây cho thấy cách thực hiện việc này.
Subspace {
SpatialRow {
SpatialColumn {
SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
SpatialPanelContent("Top Left")
}
SpatialPanel(SubspaceModifier.height(200.dp).width(400.dp)) {
SpatialPanelContent("Middle Left")
}
SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
SpatialPanelContent("Bottom Left")
}
}
SpatialColumn {
SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
SpatialPanelContent("Top Right")
}
SpatialPanel(SubspaceModifier.height(200.dp).width(400.dp)) {
SpatialPanelContent("Middle Right")
}
SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
SpatialPanelContent("Bottom Right")
}
}
}
}
@Composable
fun SpatialPanelContent(text: String) {
Column(
Modifier
.background(color = Color.Black)
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = "Panel",
color = Color.White,
fontSize = 15.sp
)
Text(
text = text,
color = Color.White,
fontSize = 25.sp,
fontWeight = FontWeight.Bold
)
}
}
Các điểm chính về mã
SpatialRow
,SpatialColumn
,SpatialBox
vàSpatialLayoutSpacer
đều là các thành phần kết hợp không gian con và phải được đặt trong một không gian con.- Sử dụng
SubspaceModifier
để tuỳ chỉnh bố cục. - Đối với bố cục có nhiều bảng điều khiển trong một hàng, bạn nên đặt bán kính cong là 825 dp bằng cách sử dụng
SubspaceModifier
để các bảng điều khiển bao quanh người dùng. Hãy xem hướng dẫn thiết kế của chúng tôi để biết thông tin chi tiết.
Sử dụng phương tiện để đặt đối tượng 3D trong bố cục
Để đặt một đối tượng 3D trong bố cục, bạn cần sử dụng một thành phần kết hợp không gian con có tên là khối lượng. Sau đây là ví dụ về cách thực hiện.
Subspace {
SpatialPanel(
SubspaceModifier.height(1500.dp).width(1500.dp)
.resizable().movable()
) {
ObjectInAVolume(true)
Box(
Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
text = "Welcome",
fontSize = 50.sp,
)
}
}
}
}
@Composable
fun ObjectInAVolume(show3DObject: Boolean) {
val xrCoreSession = checkNotNull(LocalSession.current)
val scope = rememberCoroutineScope()
if (show3DObject) {
Subspace {
Volume(
modifier = SubspaceModifier
.offset(volumeXOffset, volumeYOffset, volumeZOffset) //
Relative position
.scale(1.2f) // Scale to 120% of the size
) { parent ->
scope.launch {
// Load your 3D Object here
}
}
}
}
}
Các điểm chính về mã
- Hãy xem phần Thêm mô hình 3D vào ứng dụng để hiểu rõ hơn về cách tải nội dung 3D trong một phương tiện.
Thêm các thành phần giao diện người dùng không gian khác
Bạn có thể đặt các thành phần giao diện người dùng không gian ở bất kỳ vị trí nào trong hệ phân cấp giao diện người dùng của ứng dụng. Bạn có thể sử dụng lại các phần tử này trong giao diện người dùng 2D và các thuộc tính không gian của chúng sẽ chỉ hiển thị khi bạn bật các tính năng không gian. Điều này cho phép bạn thêm độ cao vào trình đơn, hộp thoại và các thành phần khác mà không cần viết mã hai lần. Hãy xem các ví dụ sau về giao diện người dùng không gian để hiểu rõ hơn về cách sử dụng các thành phần này.
Thành phần giao diện người dùng |
Khi tính năng không gian được bật |
Trong môi trường 2D |
---|---|---|
|
Bảng điều khiển sẽ đẩy nhẹ về sau theo chiều sâu z để hiển thị hộp thoại nâng cao |
Quay lại chế độ 2D |
|
Bảng điều khiển sẽ đẩy nhẹ về sau trong chiều sâu z để hiển thị một cửa sổ bật lên nâng cao |
Quay lại |
|
Bạn có thể đặt |
Chương trình không có độ cao không gian. |
SpatialDialog
Đây là ví dụ về một hộp thoại mở ra sau một khoảng thời gian trễ ngắn. Khi sử dụng SpatialDialog
, hộp thoại sẽ xuất hiện ở cùng độ sâu z với bảng điều khiển không gian và bảng điều khiển sẽ được đẩy lùi 125 dp khi bật tính năng không gian. Bạn cũng có thể sử dụng SpatialDialog
khi không bật tính năng không gian hoá. Trong trường hợp này, SpatialDialog
sẽ quay lại đối tác 2D, Dialog
.
@Composable
fun DelayedDialog() {
var showDialog by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
Handler(Looper.getMainLooper()).postDelayed({
showDialog = true
}, 3000)
}
if (showDialog) {
SpatialDialog (
onDismissRequest = { showDialog = false },
SpatialDialogProperties(
dismissOnBackPress = true)
){
Box(Modifier
.height(150.dp)
.width(150.dp)
) {
Button(onClick = { showDialog = false }) {
Text("OK")
}
}
}
}
}
Các điểm chính về mã
- Đây là ví dụ về
SpatialDialog
. Việc sử dụngSpatialPopUp
vàSpatialElevation
rất giống nhau. Hãy xem tài liệu tham khảo API để biết thêm thông tin chi tiết.
Tạo bảng điều khiển và bố cục tuỳ chỉnh
Để tạo các bảng điều khiển tuỳ chỉnh mà Compose for XR không hỗ trợ, bạn có thể làm việc trực tiếp với PanelEntities
và biểu đồ cảnh bằng cách sử dụng các API SceneCore
.
Neo vệ tinh quỹ đạo vào bố cục không gian và các thực thể khác
Bạn có thể neo một vệ tinh nhân tạo vào bất kỳ thực thể nào được khai báo trong Compose. Việc này liên quan đến việc khai báo một vệ tinh nhân tạo trong bố cục không gian của các phần tử giao diện người dùng như SpatialRow
, SpatialColumn
hoặc SpatialBox
. Vệ tinh nhân tạo sẽ neo vào thực thể mẹ gần nhất với vị trí bạn đã khai báo.
Hành vi của vệ tinh sẽ được xác định theo vị trí bạn khai báo:
- Trong bố cục 2D được gói trong
SpatialPanel
(như trong đoạn mã trước đó), vệ tinh sẽ neo vàoSpatialPanel
đó. - Trong
Subspace
, vệ tinh sẽ neo vào thực thể mẹ gần nhất, tức là bố cục không gian mà vệ tinh được khai báo.
Ví dụ sau đây cho thấy cách neo tàu vũ trụ vào một hàng không gian:
Subspace {
SpatialRow {
Orbiter(
position = OrbiterEdge.Top,
offset = EdgeOffset.inner(8.dp),
shape = SpatialRoundedCornerShape(size = CornerSize(50))
) {
Text(
"Hello World!",
style = MaterialTheme.typography.titleLarge,
modifier = Modifier
.background(Color.White)
.padding(16.dp)
)
}
SpatialPanel(
SubspaceModifier
.height(824.dp)
.width(1400.dp)
) {
Box(
modifier = Modifier
.background(Color.Red)
)
}
SpatialPanel(
SubspaceModifier
.height(824.dp)
.width(1400.dp)
) {
Box(
modifier = Modifier
.background(Color.Blue)
)
}
}
}
Các điểm chính về mã
- Khi bạn khai báo một vệ tinh bay quanh bên ngoài bố cục 2D, vệ tinh bay quanh sẽ neo vào thực thể mẹ gần nhất. Trong trường hợp này, vệ tinh sẽ neo vào đầu
SpatialRow
được khai báo. - Các bố cục không gian như
SpatialRow
,SpatialColumn
,SpatialBox
đều có các thực thể không có nội dung liên kết với chúng. Do đó, một vệ tinh được khai báo trong bố cục không gian sẽ liên kết với bố cục đó.
Xem thêm
- Thêm mô hình 3D vào ứng dụng
- Phát triển giao diện người dùng cho ứng dụng dựa trên Khung hiển thị Android
- Triển khai Material Design cho XR