Tìm hiểu các kiến thức cơ bản về Android XR: Phần 1 – Chế độ và Bảng điều khiển không gian

1. Trước khi bắt đầu

Kiến thức bạn sẽ học được

  • Trải nghiệm người dùng riêng biệt mà kiểu dáng XR có thể mang đến.
  • Kiến thức cơ bản về cách điều chỉnh ứng dụng để khai thác tối đa việc chạy trên thiết bị đeo đầu XR, bằng cách dùng các thành phần kết hợp do thư viện Jetpack Compose XR cung cấp.
  • Cách sử dụng các phần tử trên giao diện người dùng do thư viện Compose XR cung cấp.
  • Tại đây, bạn sẽ tìm hiểu thêm về cách tạo ứng dụng cho Android XR.

Không bao gồm

Bạn cần có

Sản phẩm bạn sẽ tạo ra

Trong lớp học lập trình này, bạn sẽ cải thiện ứng dụng màn hình đơn cơ bản để mang đến trải nghiệm người dùng sống động nhờ Android XR.

Điểm xuất phát

Kết quả cuối cùng

2. Bắt đầu thiết lập

Lấy mã nguồn

  1. Bạn có thể tìm thấy đoạn mã dành cho lớp học lập trình này trong thư mục xr-fundamentals trong kho lưu trữ GitHub xr-codelabs. Để sao chép kho lưu trữ, hãy chạy lệnh sau đây:
git clone https://github.com/android/xr-codelabs.git
  1. Ngoài ra, bạn có thể tải kho lưu trữ ở dạng định dạng tệp ZIP:

Mở dự án

  • Sau khi chạy Android Studio, hãy nhập dự án, chỉ chọn thư mục xr-fundamentals/start. Thư mục xr-fundamentals/part1 chứa đoạn mã giải pháp mà bạn có thể tham khảo bất cứ lúc nào nếu gặp khó khăn hoặc đơn giản là xem toàn bộ dự án.

Làm quen với đoạn mã

  • Sau khi mở dự án trong Android Studio, hãy dành chút thời gian để xem qua đoạn mã khởi đầu.

3. Tìm hiểu khái niệm XR concepts: Chế độ và Bảng điều khiển không gian

Trong lớp học lập trình này, bạn sẽ tìm hiểu về 2 khái niệm Android XR: chế độ và bảng điều khiển không gian. Bạn cũng sẽ tìm hiểu cách áp dụng các khái niệm này để ứng dụng chạy trên một thiết bị Android XR.

Chế độ

Trên thiết bị Android XR, các ứng dụng chạy ở một trong hai chế độ sau: chế độ Không gian chính hoặc chế độ Toàn không gian.

Chế độ Không gian chính

d779257a53898d36.jpeg

Ở chế độ Không gian chính, nhiều ứng dụng chạy song song để người dùng có thể làm nhiều việc trên nhiều ứng dụng. Các ứng dụng Android có thể chạy trong chế độ Không gian chính mà không cần sửa đổi.

Chế độ Toàn không gian

c572cdee69669a23.jpeg

Ở chế độ Toàn không gian, một ứng dụng sẽ chạy tại một thời điểm mà không bị giới hạn về không gian. Các ứng dụng khác đều bị ẩn. Các ứng dụng phải làm việc nhiều hơn để vào chế độ Toàn không gian và đảm bảo có thể dùng các chức năng bổ sung trong chế độ này.

Để tìm hiểu thêm về các chế độ này, hãy xem bài viết ​​ Chế độ Không gian chính và chế độ Toàn không gian

Bảng điều khiển không gian

Bảng điều khiển không gian là các phần tử vùng chứa hoạt động dưới dạng thành phần cơ bản của các ứng dụng Android XR.

Khi chạy ở chế độ Không gian chính, ứng dụng của bạn sẽ nằm trong một bảng điều khiển có trải nghiệm tương tự như màn hình kiểu máy tính trên một thiết bị Android có màn hình lớn.

Khi ứng dụng chạy ở chế độ Toàn không gian, bạn có thể chia nội dung của ứng dụng thành một hoặc nhiều bảng điều khiển để mang đến trải nghiệm sống động hơn.

Để tìm hiểu thêm về các bảng điều khiển, hãy xem bài viết Bảng điều khiển không gian.

4. Chạy ứng dụng trong trình mô phỏng Android XR

Trước khi bắt đầu cải thiện ứng dụng cho Android XR, bạn có thể chạy ứng dụng trong trình mô phỏng Android XR để xem giao diện của ứng dụng ở chế độ Không gian chính.

Cài đặt hình ảnh hệ thống Android XR

  1. Trước tiên, hãy mở Trình quản lý SDK trong Android Studio rồi chọn thẻ SDK Platforms (Nền tảng SDK) nếu chưa chọn. Ở góc dưới bên phải của cửa sổ Trình quản lý SDK, hãy đảm bảo rằng hộp Show package details (Hiện thông tin về gói) được chọn.
  2. Trong phần Android 14, hãy cài đặt hình ảnh trình mô phỏng Android XR ARM 64 v8a hoặc Android XR Intel x86_64. Các hình ảnh hệ thống chỉ chạy được trên máy có cùng cấu trúc (x86/ARM) với chính chúng.

Tạo thiết bị Android XR ảo

  1. Sau khi mở Device Manager (Trình quản lý thiết bị), hãy chọn XR trong cột Category (Danh mục) ở bên trái cửa sổ. Sau đó, chọn hồ sơ phần cứng XR Device (Thiết bị XR) trong danh sách rồi nhấp vào Next (Tiếp theo).

7a5f6b9c1766d837.png

  1. Trên trang tiếp theo, hãy chọn hình ảnh hệ thống mà bạn đã cài đặt ở bước trước. Nhấp vào Next (Tiếp theo) rồi chọn mọi tuỳ chọn nâng cao mà bạn muốn trước khi tạo AVD bằng cách nhấp vào Finish (Hoàn tất).
  2. Chạy ứng dụng trên AVD mà bạn đã tạo.

7cf6569ef7967d87.png

5. Thiết lập phần phụ thuộc

Để có thể bắt đầu thêm chức năng XR cụ thể vào ứng dụng, bạn sẽ cần thêm một phần phụ thuộc trên Jetpack Compose cho thư viện XR androidx.xr.compose:compose. Phần phụ thuộc này chứa mọi thành phần kết hợp mà bạn cần để tạo ra trải nghiệm Android XR tối ưu cho ứng dụng.

libs.version.toml

[versions]
...
xrCompose = "1.0.0-alpha01"

[libraries]
...
androidx-xr-compose = { group = "androidx.xr.compose", name = "compose", version.ref = "xrCompose" }

build.gradle.kts (Module :app)

dependencies {
    ...
    implementation(libs.androidx.xr.compose)
    ...
}

Sau khi cập nhật những tệp này, hãy nhớ Gradle sync (Đồng bộ hoá Gradle) để đảm bảo các phần phụ thuộc đã được tải xuống dự án của bạn.

6. Vào chế độ Toàn không gian

Để sử dụng các tính năng XR như bảng điều khiển, ứng dụng phải được chạy ở chế độ Toàn không gian. Có hai cách sau đây để ứng dụng vào chế độ Toàn không gian:

  • Theo lập trình, chẳng hạn như phản hồi với một hoạt động tương tác của người dùng trong ứng dụng
  • Vào ngay sau khi khởi chạy bằng cách thêm một lệnh vào tệp kê khai ứng dụng của bạn.

Vào chế độ Toàn không gian theo lập trình

Để vào chế độ Toàn không gian theo lập trình, bạn có thể cung cấp các thành phần trong giao diện người dùng để cho phép người dùng kiểm soát chế độ mà họ muốn dùng ứng dụng của bạn. Ngoài ra, bạn cũng có thể vào chế độ Toàn không gian khi phù hợp trong bối cảnh về cách ứng dụng được dùng. Ví dụ: hãy vào chế độ Toàn không gian khi bắt đầu xem nội dung video và thoát chế độ này khi phát xong.

Để mọi thứ đơn giản hơn, bạn có thể làm việc này trước tiên bằng cách thêm một nút vào thanh ứng dụng trên cùng để bật/tắt chế độ.

  1. Tạo một tệp mới ToggleSpaceModeButton.kt trong gói com.example.android.xrfundamentals.ui.component và thêm các thành phần kết hợp sau:

ToggleSpaceModeButton.kt

package com.example.android.xrfundamentals.ui.component

import androidx.annotation.DrawableRes
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.xr.compose.platform.LocalSpatialCapabilities
import androidx.xr.compose.platform.LocalSpatialConfiguration
import com.example.android.xrfundamentals.R
import com.example.android.xrfundamentals.ui.theme.XRFundamentalsTheme

@Composable
fun ToggleSpaceModeButton(modifier: Modifier = Modifier) {
    val spatialConfiguration = LocalSpatialConfiguration.current

    if (LocalSpatialCapabilities.current.isSpatialUiEnabled) {
        ToggleSpaceModeButton(
            modifier = modifier,
            contentDescription = "Request Home Space mode",
            iconResource = R.drawable.ic_home_space_mode,
            onClick = { spatialConfiguration.requestHomeSpaceMode() }
        )
    } else {
        ToggleSpaceModeButton(
            modifier = modifier,
            contentDescription = "Request Full Space mode",
            iconResource = R.drawable.ic_full_space_mode,
            onClick = { spatialConfiguration.requestFullSpaceMode() }
        )
    }
}

@Composable
fun ToggleSpaceModeButton(
    contentDescription: String,
    @DrawableRes iconResource: Int,
    onClick: () -> Unit,
    modifier: Modifier = Modifier
) {
    IconButton(
        modifier = modifier,
        onClick = onClick
    ) {
        Icon(
            painterResource(iconResource),
            contentDescription
        )
    }
}
  1. Thêm nút dưới dạng hành động trong TopAppBar khi ứng dụng đang chạy trên một thiết bị XR

XRFundamentalsTopAppBar.kt

import androidx.xr.compose.platform.LocalHasXrSpatialFeature

...

TopAppBar(
    ...,
    actions = {
        // Only show the mode toggle if the device supports spatial UI
        if (LocalHasXrSpatialFeature.current) {
            ToggleSpaceModeButton()
        }
    }
)

Giờ thì hãy chạy ứng dụng.

Ứng dụng chạy ở chế độ Không gian chính khi được khởi chạy. Nhấn vào nút ở trên cùng bên phải của bảng điều khiển để chuyển sang chế độ Toàn không gian.

Ứng dụng đang chạy ở chế độ Toàn không gian. Bạn sẽ nhận thấy giao diện người dùng hệ thống để thu nhỏ/đóng ứng dụng đã biến mất. Hãy nhấn vào nút ở trên cùng bên phải của bảng điều khiển để chuyển về chế độ không gian chính.

Các đoạn mã này bao gồm một số API mới của ghi chú:

  • LocalSpatialConfiguration là một thành phần cục bộ cung cấp quyền truy cập vào cấu hình không gian hiện tại của ứng dụng. Không chỉ là phương thức để yêu cầu thay đổi chế độ, thành phần này còn bao gồm cả thông tin khác, chẳng hạn như kích thước của không gian chứa ứng dụng.
  • LocalSpatialCapabilities là một thành phần cục bộ có thể dùng để xác định các chức năng không gian hiện có sẵn để ứng dụng dùng. Ngoài chế độ (Không gian chính hoặc Toàn không gian), các chức năng này bao gồm cả chức năng như âm thanh không gian và tính năng hỗ trợ nội dung 3D.
  • LocalHasXrSpatialFeature là một thành phần cục bộ có thể dùng để xác định ứng dụng có chạy trên thiết bị hỗ trợ các tính năng giao diện người dùng không gian hay không. Về cơ bản, thành phần này sẽ kiểm tra xem thiết bị có android.software.xr.immersive tính năng hệ thống hay không.

Vào chế độ Toàn không gian khi khởi chạy

Để hướng dẫn hệ điều hành bắt đầu một hoạt động ở chế độ Toàn không gian, bạn có thể thêm phần tử <property> với các thuộc tính sau trong phần tử <activity> tương ứng. Bạn chỉ nên làm như vậy nếu ít có khả năng người dùng muốn sử dụng một ứng dụng khác trong cùng thời điểm họ đang dùng ứng dụng của bạn.

AndroidManifest.xml

<activity
    android:name=".MainActivity" 
    ... >
    <property
        android:name="android.window.PROPERTY_XR_ACTIVITY_START_MODE"
        android:value="XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED" />
</activity>

Bây giờ, khi ứng dụng đã được khởi chạy, người dùng sẽ được chuyển sang chế độ Toàn không gian ngay.

abbf3d27cd2a4532.gif

Trước khi bạn tiếp tục, hãy xoá phần tử <property> nêu trên khỏi tệp kê khai để các ứng dụng thực hiện hành vi mặc định khi mở chế độ Không gian chính.

7. Chia giao diện người dùng thành nhiều bảng điều khiển

Giờ đây khi ứng dụng đã vào và thoát khỏi chế độ Toàn không gian, đã đến lúc sử dụng chế độ này hiệu quả hơn. Một cách hay để làm việc này là chia nội dung ứng dụng của bạn thành nhiều bảng điều khiển để làm đầy không gian, cũng như cho phép người dùng di chuyển và thay đổi kích thước các bảng điều khiển đó khi họ thấy phù hợp (không bắt buộc).

Nhúng ứng dụng trong một không gian phụ

Để bắt đầu hãy thêm thành phần kết hợp Subspace sau thành phần kết hợp Scaffold trong thành phần kết hợp XRFundamentalsApp. Không gian phụ là một phân vùng của không gian 3D trong ứng dụng của bạn. Trong không gian phụ, bạn có thể tạo các cấu trúc 3D (ví dụ: thêm các bảng điều khiển không gian), đặt mô hình 3D hoặc thêm chiều sâu cho nội dung 2D.

Khi chạy trên một thiết bị không phải XR, nội dung của thành phần kết hợp Subspace sẽ không bao giờ chuyển vào Thành phần. Khi chạy trên một thiết bị XR, nội dung sẽ chỉ chuyển vào Thành phần khi ứng dụng đang chạy ở chế độ Toàn không gian.

XRFundamentalsApp.kt

import androidx.xr.compose.spatial.Subspace

...

HelloAndroidXRTheme {
    Scaffold(...)
    Subspace {
    }
}

Giờ thì hãy chạy ứng dụng:

2d47561a616f4a11.gif

Khi ứng dụng của bạn có một thành phần kết hợp Subspace, thì thành phần này sẽ hiển thị thay cho nội dung 2D. Điều này có nghĩa là khi bạn nhấp vào nút để vào chế độ Toàn không gian, sẽ không có nội dung nào xuất hiện nữa. Để sửa lỗi này, bạn sẽ cần thêm 2 bảng điều khiển không gian trong một vài bước tiếp theo. Trong đó, một bảng điều khiển cần chứa nội dung chính và bảng còn lại chứa nội dung phụ.

Thêm bảng điều khiển cho nội dung chính

Để hiển thị nội dung chính ở chế độ Toàn không gian, hãy thêm SpatialPanel trong thành phần kết hợp Subspace.

Vì đây là bảng điều khiển chính của ứng dụng, nên bạn cần thêm cả Scaffold trong đó để các chế độ điều khiển trên thanh ứng dụng luôn hiển thị. Trong lớp học lập trình tiếp theo, bạn sẽ tìm hiểu về orbiter – một thành phần có thể dùng để tạo không gian cho các chế độ điều khiển thường có trên thanh ứng dụng, chẳng hạn như tính năng điều hướng và thao tác cụ thể theo ngữ cảnh.

XRFundamentalsApp.kt

import androidx.xr.compose.subspace.SpatialPanel

...

Subspace {
    SpatialPanel() {
        Scaffold(
            topBar = { XRFundamentalsTopAppBar() }
        ) { innerPadding ->
            Box(Modifier.padding(innerPadding)) {
                PrimaryCard(
                    modifier = Modifier
                        .padding(16.dp)
                        .verticalScroll(rememberScrollState())
                )
            }
        }
    }
}

Chạy lại ứng dụng và bạn sẽ thấy rằng SpatialPanel với nội dung chính hiển thị ở chế độ Toàn không gian nhưng có kích thước rất nhỏ.

89152c1991d422d4.gif

Sửa đổi bảng điều khiển chính

Để bảng điều khiển chính sử dụng được, bạn có thể điều chỉnh để bảng điều khiển lớn hơn bằng cách cung cấp một SubspaceModifier. Các đối tượng sửa đổi của không gian phụ tương tự như đối tượng sửa đổi và được dùng để sửa đổi các thành phần không gian như bảng điều khiển.

XRFundamentalsApp.kt

import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.layout.height
import androidx.xr.compose.subspace.layout.width
import androidx.compose.ui.unit.dp

...

SpatialPanel(
    modifier = SubspaceModifier
        .width(1024.dp)
        .height(800.dp)
){
    ...
}

Chạy lại ứng dụng và bảng điều khiển chính sẽ chiếm nhiều không gian hơn.

c4f28838e16a3eb8.gif

Thêm bảng điều khiển cho nội dung phụ

Bây giờ, ứng dụng của bạn đã chạy ở chế độ Toàn không gian và dùng một bảng điều khiển để hiển thị nội dung chính, đã đến lúc di chuyển nội dung phụ vào bảng điều khiển của ứng dụng. Lưu ý sử dụng một Surface trong bảng điều khiển không gian. Nếu không, sẽ không có nền cho các thẻ phụ vì bảng điều khiển sẽ trở trên trong suốt (thành phần kết hợp Scaffold đã xử lý trong bước trước).

XRFundamentalsApp.kt

Subspace {
    SpatialPanel() { ... }
    SpatialPanel(
        modifier = SubspaceModifier
            .width(340.dp)
            .height(800.dp)
    ) {
        Surface {
            SecondaryCardList(
                modifier = Modifier
                    .padding(16.dp)
                    .verticalScroll(rememberScrollState())
            )
        }
    }
}

Bây giờ, hãy chạy lại ứng dụng. Khi mới xem qua lần đầu, ứng dụng có thể xuất hiện mà không hiển thị bảng điều khiển phụ nhưng thực tế là có, vì bảng điều khiển phụ bị ẩn phía sau bảng điều khiển chính.

7db3c3428b64e482.gif

Sắp xếp bố cục bảng điều khiển trong một hàng

Cũng giống như với nội dung 2D, việc dùng hàng và cột cũng hữu ích để sắp xếp các thành phần kết hợp song song mà không bị chồng chéo. Khi làm việc với các thành phần không gian như bảng điều khiển, bạn có thể dùng thành phần kết hợp SpatialRowSpatialColumn để làm như vậy.

XRFundamentalsApp.kt

import androidx.xr.compose.subspace.SpatialRow

...

Subspace {
    SpatialRow(
        curveRadius = 825.dp
    ) {
        SpatialPanel(...) { ... }
        SpatialPanel(...) { ... }
    }
}

Chạy ứng dụng một lần nữa và bạn sẽ thấy rằng các bảng điều khiển được sắp xếp theo bố cục lần lượt trong một hàng. Ngoài ra, vì curveRadius được cung cấp cho SpatialRow, nên các bảng điều khiển sẽ uốn cong xung quanh người dùng thay vì ở trong cùng một mặt phẳng, mang đến một trải nghiệm toàn diện.

7455811775088baf.gif

Điều chỉnh để bảng điều khiển có thể thay đổi kích thước

Nhằm cho phép người dùng kiểm soát giao diện của ứng dụng, bạn có thể điều chỉnh để bảng điều khiển có thể thay đổi kích thước bằng cách dùng đối tượng sửa đổi không gian phụ resizable.

Theo mặc định, các bảng điều khiển thay đổi được kích thước có thể giảm kích thước xuống 0 hoặc mở rộng không giới hạn. Do đó, bạn có thể cần dành thời gian để đặt các tham số minimumSizemaximumSize thích hợp dựa trên nội dung mà chúng sẽ chứa.

Hãy xem tài liệu tham khảo để biết thêm chi tiết về mọi tham số mà đối tượng sửa đổi resizable hỗ trợ.

XRFundamentalsApp.kt

import androidx.xr.compose.subspace.layout.resizable

...

SpatialPanel(
    modifier = SubspaceModifier
        ...
        .resizable(true)
)

2ff2db33032fd251.gif

Điều chỉnh để bảng điều khiển có thể di chuyển

Tương tự, bạn có thể điều chỉnh để bảng điều khiển có thể di chuyển bằng cách dùng đối tượng sửa đổi không gian phụ movable.

XRFundamentalsApp.kt

import androidx.xr.compose.subspace.layout.movable

...

SpatialPanel(
    modifier = SubspaceModifier
        ...
        .movable(true)
)

12b6166645ea1be.gif

Hãy xem tài liệu tham khảo để biết thêm chi tiết về mọi tham số mà đối tượng sửa đổi movable hỗ trợ.

8. Xin chúc mừng

Để tiếp tục tìm hiểu về cách khai thác tối đa XR, hãy tham khảo các tài nguyên và bài tập sau đây. Bạn cũng có thể đăng ký tham gia chương trình đào tạo về XR!

Tài liệu đọc thêm

Thử thách

  • Sử dụng các tham số có sẵn cho đối tượng sửa đổi không gian phụ resizablemovable.
  • Thêm các bảng điều khiển bổ sung.
  • Dùng các thành phần không gian khác như hộp thoại không gian

Tài liệu tham khảo