Hướng dẫn

Đưa Androidify lên XR bằng SDK Jetpack XR

Đọc trong 9 phút
Dereck Bridie
Kỹ sư quan hệ với nhà phát triển

Samsung Galaxy XR đã ra mắt, chạy trên Android XR! Bài đăng này trên blog là một phần của Tuần lễ tiêu điểm Android XR, nơi chúng tôi cung cấp các tài nguyên (bài đăng trên blog, video, mã mẫu và nhiều tài nguyên khác) được thiết kế để giúp bạn tìm hiểu, xây dựng và chuẩn bị ứng dụng cho Android XR.

Với việc ra mắt Samsung Galaxy XR , thiết bị đầu tiên chạy trên Android XR đã chính thức ra mắt. Giờ đây, mọi người có thể thưởng thức nhiều ứng dụng yêu thích của mình trên Cửa hàng Play ở một chiều không gian hoàn toàn mới: chiều thứ ba!

Chiều thứ ba là một chiều không gian rộng rãi, với nhiều không gian cho các ứng dụng của bạn. Hãy bắt đầu ngay hôm nay bằng cách sử dụng bất kỳ công cụ nào phù hợp với ứng dụng của bạn. Ví dụ: bạn có thể sử dụng SDK Jetpack XR để tạo trải nghiệm XR sống động bằng các công cụ cho nhà phát triển Android hiện đại như Kotlin và Compose.

Trong bài đăng này trên blog, chúng tôi sẽ kể cho bạn về hành trình của chính mình khi đưa ứng dụng Androidify yêu thích lên XR, đồng thời đề cập đến những kiến thức cơ bản cần thiết để đưa ứng dụng của bạn lên XR.

Tham quan Androidify

Androidify là một ứng dụng nguồn mở cho phép bạn tạo bot Android bằng một số công nghệ mới nhất như Gemini, CameraX, Navigation 3 và tất nhiên là Jetpack Compose. Androidify ban đầu được thiết kế để có giao diện đẹp mắt trên điện thoại, thiết bị có thể gập lại và máy tính bảng bằng cách tạo bố cục thích ứng.

customize.png

Androidify có giao diện đẹp mắt trên nhiều kiểu dáng

Một trụ cột chính của bố cục thích ứng là các thành phần kết hợp có thể sử dụng lại. Jetpack Compose giúp bạn tạo các thành phần giao diện người dùng nhỏ gọn có thể được bố trí theo nhiều cách để tạo trải nghiệm người dùng trực quan, bất kể người dùng đang sử dụng loại thiết bị nào. Trên thực tế, Androidify tương thích với Android XR mà không cần sửa đổi ứng dụng!

customize_2.png

Androidify thích ứng với XR bằng bố cục thích ứng với màn hình lớn mà không cần thay đổi mã

Các ứng dụng không có cách xử lý đặc biệt cho Android XR có thể được chạy đa nhiệm trong một cửa sổ có kích thước phù hợp và hoạt động giống như trên màn hình lớn. Do đó, Androidify đã có đầy đủ tính năng trên Android XR mà không cần thêm công việc nào! Tuy nhiên, chúng tôi không muốn dừng lại ở đó, vì vậy, chúng tôi quyết định nỗ lực hơn nữa và tạo một ứng dụng dành riêng cho XR để mang đến trải nghiệm thú vị cho người dùng XR.

Làm quen với XR

Hãy xem các khái niệm cơ bản chính cho Android XR, bắt đầu từ 2 chế độ mà ứng dụng có thể chạy: Không gian chính và Toàn bộ không gian.

homespace.png
Các ứng dụng trong Không gian chính
homespace2.png
Ứng dụng trong Toàn bộ không gian

Trong Không gian chính, nhiều ứng dụng có thể chạy song song để người dùng có thể làm nhiều việc trên nhiều cửa sổ. Theo đó, chế độ này giống như chế độ cửa sổ kiểu máy tính trên thiết bị Android có màn hình lớn, nhưng trong không gian ảo!

Trong Toàn bộ không gian, ứng dụng không có ranh giới không gian và có thể tận dụng đầy đủ các tính năng không gian của Android XR, chẳng hạn như giao diện người dùng không gian và kiểm soát môi trường ảo.

Mặc dù có vẻ hấp dẫn khi chỉ chạy ứng dụng ở chế độ Toàn bộ không gian, nhưng người dùng có thể muốn chạy đa nhiệm với ứng dụng của bạn, vì vậy, việc hỗ trợ cả hai chế độ sẽ giúp cải thiện trải nghiệm người dùng.

Thiết kế cho chiều không gian mới của Androidify

Một ứng dụng thú vị bắt đầu từ một thiết kế tuyệt vời. Ivy Knight, Chuyên gia thiết kế cấp cao của Nhóm quan hệ với nhà phát triển Android, đã đảm nhận nhiệm vụ thiết kế lại Androidify cho XR. Mời Ivy chia sẻ!

Việc thiết kế cho XR đòi hỏi một phương pháp độc đáo, nhưng thực tế vẫn có nhiều điểm chung với thiết kế cho thiết bị di động. Chúng tôi bắt đầu bằng cách nghĩ về việc chứa đựng: cách sắp xếp và nhóm các thành phần giao diện người dùng trong không gian phụ, bằng cách hiển thị rõ ràng ranh giới hoặc ngầm định ranh giới. Chúng tôi cũng học cách chấp nhận tất cả các kích thước khác nhau của thành phần giao diện người dùng không gian, được thiết kế để điều chỉnh và di chuyển theo phản ứng của người dùng. Như chúng tôi đã làm với Androidify, hãy tạo bố cục thích ứng để bạn có thể chia bố cục thành các phần cho giao diện người dùng không gian.

Bắt đầu thiết kế với Không gian chính

May mắn là Android XR cho phép bạn bắt đầu với ứng dụng hiện tại của mình cho Không gian chính, vì vậy, chúng tôi có thể chuyển sang các thiết kế XR mở rộng bằng cách chỉ thêm thanh công cụ cửa sổ và nút chuyển đổi Toàn bộ không gian.

Chúng tôi cũng xem xét các tính năng phần cứng có thể có và cách người dùng tương tác với các tính năng đó. Bố cục dành cho thiết bị di động của Androidify thích ứng với nhiều tư thế, kích thước lớp và số lượng camera để cung cấp thêm các lựa chọn chụp ảnh. Theo mô hình này, chúng tôi cũng phải điều chỉnh bố cục camera cho các thiết bị đeo đầu. Chúng tôi cũng cần điều chỉnh văn bản để phù hợp với khoảng cách của giao diện người dùng với người dùng.

Thiết kế cho sự thay đổi lớn hơn sang Toàn bộ không gian

Toàn bộ không gian là sự thay đổi lớn nhất, nhưng mang đến cho chúng tôi không gian sáng tạo nhất để điều chỉnh thiết kế của mình. 

tablet_to_xr.webp
Từ máy tính bảng sang XR

Androidify sử dụng tính năng chứa đựng trực quan (hoặc ngăn) để nhóm các tính năng có nền và đường viền, chẳng hạn như ngăn "Chụp hoặc chọn ảnh". Chúng tôi cũng sử dụng các thành phần như thanh ứng dụng trên cùng để tạo tính năng chứa đựng tự nhiên bằng cách đóng khung các ngăn khác. Cuối cùng, tính năng chứa đựng vốn có được gợi ý bởi khoảng cách của một số thành phần với các thành phần khác, chẳng hạn như nút dưới cùng "Bắt đầu chuyển đổi", nằm gần ngăn "Chọn màu bot của tôi".

Bảng điều khiển không gian giúp dễ dàng tách biệt. Để quyết định cách điều chỉnh thiết kế cho thiết bị di động cho bảng điều khiển không gian, hãy thử xoá các nền tảng, bắt đầu từ nền tảng ở xa nhất rồi di chuyển về phía trước. Xem bạn có thể xoá bao nhiêu nền và những gì còn lại. Sau khi chúng tôi thực hiện bài tập này cho Androidify, những gì còn lại là hình nguệch ngoạc màu xanh lục lớn của Android. Hình nguệch ngoạc không chỉ đóng vai trò là khoảnh khắc xây dựng thương hiệu và nền, mà còn là điểm neo cho nội dung trong không gian 3D.

Việc thiết lập điểm neo này giúp chúng tôi dễ dàng hình dung cách các thành phần có thể di chuyển xung quanh điểm neo và cách chúng tôi có thể sử dụng khoảng cách để tách biệt và chuyển đổi phần còn lại của trải nghiệm người dùng.

Các mẹo thiết kế khác giúp ứng dụng của bạn có không gian

  • Cho phép các thành phần không bị chứa đựng: Tách biệt các thành phần và cung cấp cho chúng một không gian thực (không gian). Đã đến lúc cung cấp cho các thành phần giao diện người dùng đó một không gian để "thở".
  • Xoá nền tảng: Ẩn nền, xem điều đó ảnh hưởng đến thiết kế của bạn như thế nào.
  • Tạo động lực bằng chuyển động: Bạn đang sử dụng các hiệu ứng chuyển đổi trong ứng dụng của mình như thế nào? Sử dụng nhân vật đó để hình dung ứng dụng của bạn tách biệt thành VR.
  • Chọn điểm neo: Đừng để người dùng bị lạc trong không gian. Hãy có một thành phần giúp thu thập hoặc làm nền cho giao diện người dùng.

Để biết thêm về các mẫu thiết kế giao diện người dùng XR, hãy xem bài viết Thiết kế cho Android XR trên trang web Nhà phát triển Android.

Kiến thức cơ bản về giao diện người dùng không gian

Bây giờ chúng ta đã đề cập đến trải nghiệm của Ivy khi điều chỉnh tư duy trong khi thiết kế Androidify cho XR, hãy nói về việc phát triển giao diện người dùng không gian. Việc phát triển giao diện người dùng không gian bằng SDK Jetpack XR sẽ quen thuộc nếu bạn đã quen làm việc với các công cụ và thư viện Android hiện đại. Bạn sẽ thấy các khái niệm mà bạn đã quen thuộc, chẳng hạn như tạo bố cục bằng Compose. Trên thực tế, bố cục không gian thực sự tương tự như bố cục 2D sử dụng hàng, cột và khoảng cách:

spatialrows.png

Các thành phần này được sắp xếp trong SpatialRows và SpatialColumns

Các thành phần không gian được hiển thị ở đây là SpatialPanel các thành phần kết hợp, cho phép bạn hiển thị nội dung 2D như văn bản, nút và video.

Subspace {
    SpatialPanel(
        SubspaceModifier
            .height(824.dp)
            .width(1400.dp)
    ) {
        Text("I'm a panel!")
    }
}

SpatialPanel là một thành phần kết hợp không gian phụ. Các thành phần kết hợp không gian phụ phải được chứa trong một Không gian phụ và được sửa đổi bởi các đối tượng SubspaceModifier. Không gian phụ có thể được đặt ở bất kỳ đâu trong hệ phân cấp giao diện người dùng của ứng dụng và chỉ có thể chứa các thành phần kết hợp Không gian phụ.Các đối tượng SubspaceModifier cũng thực sự tương tự như các đối tượng Modifier: chúng kiểm soát các tham số như kích thước và vị trí.

Một Orbiter có thể được gắn vào SpatialPanel và di chuyển cùng với nội dung mà nó được gắn vào. Chúng thường được dùng để cung cấp các chế độ điều khiển theo ngữ cảnh về nội dung mà chúng được gắn vào, giúp nội dung trở thành tiêu điểm chính. Chúng có thể được đặt ở bất kỳ vị trí nào trong 4 cạnh của nội dung, ở khoảng cách có thể định cấu hình.

orbiter.png
Một Orbiter được gắn vào cuối SpatialPanel

Còn nhiều thành phần giao diện người dùng không gian khác, nhưng đây là những thành phần chính mà chúng tôi đã sử dụng để tạo bố cục không gian cho Androidify.

Bắt đầu phát triển cho XR

Hãy bắt đầu với việc thiết lập dự án. Chúng tôi đã thêm phần phụ thuộc Jetpack XR Compose mà bạn có thể tìm thấy trên trang phần phụ thuộc Jetpack XR.

Chúng tôi đã thêm mã cho một nút chuyển đổi người dùng sang Toàn bộ không gian, bắt đầu bằng việc phát hiện khả năng thực hiện việc đó:

@Composable
fun couldRequestFullSpace(): Boolean =
   LocalSpatialConfiguration.current.hasXrSpatialFeature && 
   !LocalSpatialCapabilities.current.isSpatialUiEnabled
}

Sau đó, chúng tôi đã tạo một thành phần nút mới sử dụng biểu tượng Mở rộng nội dung cho các bố cục hiện có và cung cấp cho nút đó hành vi onClick:

@Composable

fun RequestFullSpaceIconButton() {
   if (!couldRequestFullSpace()) return
   val session = LocalSession.current ?: return

   IconButton(
       onClick = {
           session.scene.requestFullSpaceMode()
       },
   ) {
       Icon(
           imageVector =  
               vectorResource(R.drawable.expand_content_24px),
           contentDescription = 
               stringResource("To Full Space"),
       )
   }
}

Bây giờ, việc nhấp vào nút đó chỉ hiển thị bố cục Trung bình trong Toàn bộ không gian. Chúng tôi có thể kiểm tra các khả năng không gian và xác định xem giao diện người dùng không gian có thể được hiển thị hay không. Trong trường hợp đó, chúng tôi sẽ hiển thị bố cục không gian mới:

@Composable

fun HomeScreenContents(layoutType: HomeScreenLayoutType) {
   val layoutType = when {
      LocalSpatialCapabilities.current.isSpatialUiEnabled -> 
          HomeScreenLayoutType.Spatial
      isAtLeastMedium() -> HomeScreenLayoutType.Medium
      else -> HomeScreenLayoutType.Compact
   }

   when (layoutType) {
      HomeScreenLayoutType.Compact ->
          HomeScreenCompactPager(...)

      HomeScreenLayoutType.Medium ->
          HomeScreenMediumContents(...)

      HomeScreenLayoutType.Spatial ->
          HomeScreenContentsSpatial(...)
   }
}

Triển khai thiết kế cho Màn hình chính

Hãy quay lại thiết kế không gian cho Màn hình chính trong Toàn bộ không gian để hiểu cách triển khai thiết kế đó.

customize_3.png

Chúng tôi xác định 2 thành phần SpatialPanel ở đây: một bảng điều khiển chứa thẻ video ở bên phải và một bảng điều khiển chứa giao diện người dùng chính. Cuối cùng, có một Orbiter được gắn vào đầu. Hãy bắt đầu với bảng điều khiển trình phát video:

@Composable
fun HomeScreenContentsSpatial(...) {
   Subspace {
      SpatialPanel(SubspaceModifier
                   .fillMaxWidth(0.2f)
                   .fillMaxHeight(0.8f)
                   .aspectRatio(0.77f)
                   .rotate(0f, 0f, 5f),
      ) {
          VideoPlayer(videoLink)
      }
   }
}

Chúng tôi chỉ cần sử dụng lại thành phần VideoPlayer 2D từ các bố cục thông thường vào SpatialPanel mà không cần thay đổi gì thêm! Đây là giao diện độc lập:

bluetiel.png

Bảng điều khiển nội dung chính cũng tương tự: chúng tôi đã sử dụng lại nội dung bảng điều khiển trung bình trong SpatialPanel.

SpatialPanel(SubspaceModifier.fillMaxSize(),
             resizePolicy = ResizePolicy(
                 shouldMaintainAspectRatio = true
             ),
             dragPolicy = MovePolicy()
) {
    Box {
        FillBackground(R.drawable.squiggle_full)
        HomeScreenSpatialMainContent(...)
    }
}

Chúng tôi đã cung cấp cho bảng điều khiển này một ResizePolicy, cung cấp cho bảng điều khiển một số ô điều khiển gần các cạnh để người dùng có thể đổi kích thước bảng điều khiển. Bảng điều khiển này cũng có một MovePolicy, cho phép người dùng kéo bảng điều khiển xung quanh.

customize_4.png

Việc đặt các thành phần này trong cùng một Không gian phụ sẽ khiến chúng độc lập với nhau, vì vậy, chúng tôi đã tạo bảng điều khiển VideoPlayer thành thành phần con của bảng điều khiển nội dung chính. Điều này khiến bảng điều khiển VideoPlayer di chuyển khi bảng điều khiển nội dung chính được kéo thông qua mối quan hệ mẹ con.

@Composable
fun HomeScreenContentsSpatial(...) {
   Subspace {
       SpatialPanel(SubspaceModifier..., resizePolicy, dragPolicy) {
           Box {
               FillBackground(R.drawable.squiggle_full)
               HomeScreenSpatialMainContent(...)
           }
           Subspace {
              SpatialPanel(SubspaceModifier...) {
                  VideoPlayer(videoLink)
              }
           }
       }
   }
}

Đó là cách chúng tôi tạo màn hình đầu tiên!

Chuyển sang các màn hình khác

Tôi cũng sẽ trình bày ngắn gọn về một số màn hình khác, nêu bật các điểm cần cân nhắc cụ thể cho từng màn hình.

fullspace.png
Màn hình tạo trong Toàn bộ không gian

Ở đây, chúng tôi đã sử dụng các thành phần kết hợp SpatialRow và SpatialColumn để tạo bố cục phù hợp với không gian xem được đề xuất, đồng thời sử dụng lại các thành phần từ bố cục Trung bình.

fullspace_2.png

Màn hình kết quả trong Toàn bộ không gian: Một bot được tạo bằng câu lệnh: mũ bóng chày màu đỏ, kính râm phi công, áo phông màu xanh nhạt, quần soóc kẻ sọc đỏ và trắng, dép xỏ ngón màu xanh lục và đang cầm vợt tennis.


Màn hình kết quả hiển thị các câu trích dẫn bổ sung bằng hiệu ứng làm mờ, cho phép chúng mờ dần ở gần các cạnh của màn hình. Màn hình này cũng sử dụng hiệu ứng chuyển đổi 3D thực tế khi xem dữ liệu đầu vào đã sử dụng, lật hình ảnh trong không gian.

Phát hành lên Cửa hàng Google Play

Giờ đây, ứng dụng đã sẵn sàng cho XR với các bố cục không gian, chúng tôi đã phát hành ứng dụng đó lên Cửa hàng Play. Có một thay đổi quan trọng cuối cùng mà chúng tôi đã thực hiện đối với tệp AndroidManifest.xml của ứng dụng:

<!-- Androidify can use XR features if they're available; they're not required. -->
<uses-feature android:name="android.software.xr.api.spatial" 
              android:required="false" />

Điều này cho phép Cửa hàng Play biết rằng ứng dụng này có các tính năng dành riêng cho XR, hiển thị huy hiệu cho người dùng biết rằng ứng dụng được tạo cho XR:

androidify2.png
Androidify như trong Cửa hàng Google Play trên Android XR


Khi tải bản phát hành lên, chúng tôi không cần thực hiện bất kỳ bước đặc biệt nào để phát hành cho XR: cùng một ứng dụng được phân phối như bình thường cho người dùng trên kênh dành cho thiết bị di động cũng như cho người dùng trên thiết bị XR! Tuy nhiên, bạn có thể chọn thêm ảnh chụp màn hình dành riêng cho XR của ứng dụng hoặc thậm chí tải bản xem trước sống động của ứng dụng lên bằng thành phần video không gian. Trên thiết bị Android XR, Cửa hàng Play sẽ tự động hiển thị bản xem trước 3D sống động này, cho phép người dùng trải nghiệm độ sâu và quy mô của nội dung trước khi cài đặt ứng dụng.

Bắt đầu xây dựng trải nghiệm của riêng bạn ngay hôm nay

Androidify là một ví dụ tuyệt vời về cách không gian hoá một ứng dụng Jetpack Compose 2D hiện có. Hôm nay, chúng tôi đã trình bày toàn bộ quy trình phát triển giao diện người dùng không gian cho Androidify, từ thiết kế đến mã đến phát hành. Chúng tôi đã sửa đổi các thiết kế hiện có để phù hợp với các mô hình không gian, sử dụng các thành phần kết hợp SpatialPanel và Orbiter để tạo bố cục không gian hiển thị khi người dùng chuyển sang Toàn bộ không gian và cuối cùng, phát hành phiên bản mới của ứng dụng lên Cửa hàng Play.

Chúng tôi hy vọng bài đăng này trên blog đã giúp bạn hiểu cách đưa ứng dụng của riêng mình lên Android XR! Dưới đây là một số đường liên kết khác có thể giúp bạn:

Tác giả:

Tiếp tục đọc