ハウツー

Jetpack XR SDK を使用して Androidify を XR に導入する

所要時間: 9 分
2025 年 10 月 22 日
Dereck Bridie
デベロッパー リレーション エンジニア

Samsung Galaxy XR がリリースされました。 _Android XR を搭載しています。_このブログ投稿は、 Android XR Spotlight Weekの一環として公開されています。このイベントでは、Android XR 向けにアプリを学習、構築、準備するのに役立つリソース(ブログ投稿、動画、サンプルコードなど)を提供しています。

Android XR を搭載した初のデバイス、Samsung Galaxy XR が正式にリリースされました。ユーザーは、Google Play ストアのお気に入りのアプリをまったく新しい次元、つまり 3 次元で楽しめるようになりました。

3 次元は広々としており、アプリを配置するスペースも十分あります。アプリに適したツールを使用して、今すぐ始めましょう。たとえば、Jetpack XR SDK を使用すると、Kotlin や Compose などの最新の Android 開発ツールを使用して、没入感のある XR エクスペリエンスを構築できます。

このブログ投稿では、Google が愛する Androidify アプリの気まぐれさを XR に導入した過程と、アプリを XR に導入するために必要な基本事項について説明します。

Androidify のツアー

Androidify は、Gemini、CameraX、Navigation 3、Jetpack Compose などの最新テクノロジーを使用して Android ボットを作成できるオープンソース アプリです。Androidify は、アダプティブ レイアウトを作成することで、スマートフォン、折りたたみ式デバイス、タブレットで美しく表示されるように設計されました。

customize.png

Androidify はさまざまなフォーム ファクタで美しく表示されます

アダプティブ レイアウトの重要な柱は、再利用可能なコンポーザブルです。Jetpack Compose を使用すると、ユーザーが使用しているデバイスの種類に関係なく、直感的なユーザー エクスペリエンスを実現するためにさまざまな方法でレイアウトできる、小さな UI コンポーネントを作成できます。実際、Androidify はアプリを変更することなく Android XR と互換性があります。

customize_2.png

Androidify は、コードを変更することなく、大画面対応のレスポンシブ レイアウトを使用して XR に適応します

Android XR の特別な処理を行っていないアプリは、適切なサイズのウィンドウでマルチタスクを実行でき、大画面の場合とほぼ同じように動作します。このため、Androidify は追加の作業なしで Android XR で完全に機能します。しかし、Google はここで止まることなく、XR ユーザーに楽しいエクスペリエンスを提供するために、XR に特化したアプリを作成することにしました。

XR での方向の把握

Android XR の基本的なコンセプトについて説明します。まず、アプリを実行できる 2 つのモード(ホームスペースとフルスペース)から始めましょう。

homespace.png
ホームスペースのアプリ
homespace2.png
フルスペースのアプリ

ホームスペースでは、複数のアプリを並べて実行できるため、ユーザーはさまざまなウィンドウでマルチタスクを実行できます。その意味では、大画面の Android デバイスでのデスクトップ ウィンドウとよく似ていますが、仮想空間で行われます。

フルスペースでは、アプリにスペースの境界がなく、空間 UI や仮想環境の制御など、Android XR の空間機能をフル活用できます。

アプリをフルスペースでのみ実行したくなるかもしれませんが、ユーザーはアプリでマルチタスクを実行したい場合があるため、両方をサポートすることでユーザー エクスペリエンスが向上します。

Androidify の新しい次元に対応した設計

楽しいアプリは優れたデザインから始まります。Android DevRel のシニア デザイン アドボケートである Ivy Knight は、Androidify の既存のデザインを基に、XR 向けの新しいデザインを考案しました。Ivy さん、お願いします。

XR 向けの設計には独自のアプローチが必要でしたが、実際にはモバイル デザインと多くの共通点がありました。まず、包含について考えました。境界を明確に示すか、暗示的に示すことで、サブスペース内の UI 要素を整理してグループ化する方法です。また、ユーザーに応じて調整して移動する空間 UI 要素のさまざまなサイズに対応する方法も学びました。Androidify の場合と同様に、アダプティブ レイアウトを使用して構築することで、空間 UI のレイアウトをパーツに分割できます。

ホームスペースから設計を開始する

幸いなことに、Android XR では、ホームスペースで現在のアプリをそのまま使用できるため、ウィンドウ ツールバーとフルスペース切り替えボタンを追加するだけで、拡張された XR デザインに移行できました。

また、考えられるハードウェア機能と、ユーザーがそれらを操作する方法についても検討しました。Androidify のモバイル レイアウトは、さまざまな姿勢、クラスサイズ、カメラの数に合わせて調整され、写真のオプションが増えます。このモデルに沿って、ヘッドセット デバイスのカメラ レイアウトも調整する必要がありました。また、UI とユーザーの距離を考慮して、テキストを調整する必要もありました

フルスペースへの大きな移行に対応した設計

フルスペースは最大の移行でしたが、デザインを調整するための創造的な余地が最も大きくなりました。

tablet_to_xr.webp
タブレットから XR へ

Androidify では、視覚的な包含(ペイン)を使用して、[写真を撮るか選択する] ペインのように、背景とアウトラインで機能をグループ化します。また、トップ アプリバーなどのコンポーネントを使用して、他のペインを囲むことで自然な包含を作成しました。最後に、[変換を開始] 下部ボタンなど、特定の要素が他の要素に近いことで、本質的な包含が示されます。このボタンは [ボットの色を選択] ペインの近くにあります。

空間パネルを使用すると、簡単に分離できます。モバイル デザインを空間パネルにどのように適応させるかを決めるには、最も奥にあるサーフェスから順にサーフェスを削除してみてください。削除できる背景の数と残りの背景を確認します。Androidify でこの操作を行った後、残ったのは大きな緑色の Android の曲線でした。この曲線は、ブランディングの瞬間と背景として機能するだけでなく、3D 空間のコンテンツのアンカーとしても機能しました。

このアンカーを設定することで、要素がどのように移動するかを想像しやすくなり、近接性を使用して残りのユーザー エクスペリエンスを分離して変換する方法を把握しやすくなりました。

アプリを空間化するためのその他の設計のヒント

  • 包含しない: コンポーネントを分離し、実際の(空間)スペースを与えます。UI 要素に余裕を持たせる必要があります。
  • サーフェスを削除する: 背景を非表示にして、デザインにどのような影響があるかを確認します。
  • モーションで動機付ける: アプリでトランジションをどのように使用していますか?そのキャラクターを使用して、アプリが VR に移行する様子を想像してください。
  • アンカーを選択する: ユーザーが空間で迷わないようにします。UI を収集または固定する要素を用意します。

XR UI デザイン パターンの詳細については、Android デベロッパーの Android XR 向けのデザインをご覧ください。

空間 UI の基本

Ivy が Androidify を XR 向けに設計する際に考え方をどのように適応させたかについて説明したので、空間 UI の開発について説明します。最新の Android ツールとライブラリの使用に慣れている場合は、Jetpack XR SDK を使用した空間 UI の開発は簡単です。Compose でレイアウトを作成するなど、すでに慣れているコンセプトを使用できます。実際、空間レイアウトは、行、列、スペーサーを使用した 2D レイアウトと非常によく似ています。

spatialrows.png

これらの要素はSpatialRowsSpatialColumnsに配置されます

ここに示されている空間要素は SpatialPanel コンポーザブルで、テキスト、ボタン、動画などの 2D コンテンツを表示できます。

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

SpatialPanel はサブスペース コンポーザブルです。サブスペース コンポーザブルはサブスペース内に含める必要があり、SubspaceModifier オブジェクトによって変更されます。サブスペースはアプリの UI 階層内の任意の場所に配置でき、サブスペース コンポーザブルのみを含めることができます。SubspaceModifier オブジェクトは Modifier オブジェクトと非常によく似ており、サイズや位置などのパラメータを制御します。

Orbiter SpatialPanel に接続して、接続先のコンテンツと一緒に移動できます。多くの場合、接続先のコンテンツに関するコンテキストに応じたコントロールを提供するために使用され、コンテンツが主な焦点となります。コンテンツの 4 辺のいずれかに、構成可能な距離で配置できます。

orbiter.png
Orbiter が SpatialPanel の下部に接続されています

空間 UI 要素は他にもたくさんありますが、Androidify の空間レイアウトを作成するために使用した主な要素はこれらです。

XR 開発を始める

プロジェクトの設定から始めましょう。Jetpack XR の依存関係ページにある Jetpack XR Compose の依存関係を追加しました。

ユーザーをフルスペースに移行するボタンのコードを追加しました。まず、その機能があるかどうかを検出します。

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

次に、既存のレイアウトに [コンテンツを展開] アイコンを使用する新しいボタン コンポーネントを作成し、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"),
       )
   }
}

このボタンをクリックすると、フルスペースに中サイズのレイアウトが表示されます。空間機能を確認して、空間 UI を表示できるかどうかを判断できます。その場合は、新しい空間レイアウトを表示します。

  @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(...)
   }
}

ホーム画面のデザインを実装する

フルスペースのホーム画面の空間デザインに戻って、どのように実装されたかを見てみましょう。

customize_3.png

ここでは、2 つの SpatialPanel 要素を特定しました。1 つは右側の動画カードが入っているパネル、もう 1 つはメイン UI が入っているパネルです。最後に、上部に Orbiter が接続されています。動画プレーヤー パネルから始めましょう。

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

通常のレイアウトの 2D VideoPlayer コンポーネントを SpatialPanel に再利用しただけで、追加の変更は行っていません。単独で表示すると次のようになります。

bluetiel.png

メイン コンテンツ パネルも同様です。中サイズのパネル コンテンツを SpatialPanel で再利用しました。

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

このパネルには ResizePolicy が設定されています。これにより、パネルの端にユーザーがパネルのサイズを変更できるハンドルが表示されます。また、MovePolicy も設定されているため、ユーザーはパネルをドラッグして移動できます。

customize_4.png

同じサブスペースに配置すると、互いに独立するため、VideoPlayer パネルをメイン コンテンツ パネルの子にしました。これにより、親子関係を通じてメイン コンテンツ パネルがドラッグされると、VideoPlayer パネルが移動します。

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

これが最初の画面の作成方法です。

他の画面に移動する

他の画面についても簡単に説明し、それぞれの画面で考慮した点を紹介します。

fullspace.png
フルスペースの作成画面

ここでは、SpatialRow コンポーザブルと SpatialColumn コンポーザブルを使用して、推奨される表示スペースに収まるレイアウトを作成しました。ここでも、中サイズのレイアウトのコンポーネントを再利用しています。

fullspace_2.png

フルスペースの結果画面: プロンプトで生成されたボット: 赤い野球帽、アビエイター サングラス、水色の T シャツ、赤と白のチェック柄のショートパンツ、緑色のビーチサンダルを履き、テニスラケットを持っています。


結果画面には、フェザリング効果を使用して補完的な引用が表示され、画面の端に近づくとフェードアウトします。また、使用された入力を表示する際には実際の 3D トランジションが使用され、空間内で画像が反転します。

Google Play ストアに公開する

空間レイアウトを使用してアプリを XR に対応させたので、Google Play ストアにリリースしました。アプリの AndroidManifest.xml ファイルに最後に行った重要な変更は次のとおりです。

  <!-- 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" />

これにより、Google Play ストアは、このアプリに XR に特化した機能があることを認識し、アプリが XR を念頭に置いて作成されたことをユーザーに知らせるバッジを表示します。

androidify2.png [
Android XR の Google Play ストアに表示されている Androidify
]


リリースをアップロードする際に、XR 向けにリリースするための特別な手順は必要ありません。モバイル トラックのユーザーと XR デバイスのユーザーに同じアプリが通常どおり配信されます。 ただし、アプリの XR 固有のスクリーンショットを追加したり、空間動画アセットを使用してアプリの没入型プレビューをアップロードしたりすることもできます。Android XR デバイスでは、Google Play ストアに没入型 3D プレビューとして自動的に表示されるため、ユーザーはアプリをインストールする前にコンテンツの奥行きとスケールを体験できます。

今すぐ独自のエクスペリエンスを構築しましょう

Androidify は、既存の 2D Jetpack Compose アプリを空間化する方法を示す優れた例です。今回は、Androidify の空間 UI を設計からコード、公開まで開発する全プロセスを紹介しました。既存のデザインを空間パラダイムに対応するように変更し、SpatialPanel コンポーザブルと Orbiter コンポーザブルを使用して、ユーザーがフルスペースに入ったときに表示される空間レイアウトを作成し、最後にアプリの新しいバージョンを Google Play ストアにリリースしました。

このブログ投稿が、独自のアプリを Android XR に導入する方法を理解するのに役立つことを願っています。以下に、役立つ可能性のあるリンクをいくつか紹介します。

作成者:

続きを読む