מדריכים

העברת Androidify ל-XR באמצעות Jetpack XR SDK

משך הקריאה: 9 דקות
Dereck Bridie
מהנדס יחסי מפתחים

‫Samsung Galaxy XR כבר כאן, והוא מבוסס על Android XR! הפוסט הזה בבלוג הוא חלק מ שבוע ההדגשה של Android XR, שבו אנחנו מספקים משאבים – פוסטים בבלוג, סרטונים, קוד לדוגמה ועוד – שנועדו לעזור לכם ללמוד, ליצור ולהכין את האפליקציות שלכם ל-Android XR.

עם ההשקה של Samsung Galaxy XR , המכשיר הראשון שמתבסס על Android XR, הוא כבר כאן. עכשיו אפשר ליהנות מרבות מהאפליקציות האהובות בחנות Play במימד חדש לגמרי: המימד השלישי!

המימד השלישי הוא רחב, ויש בו הרבה מקום גם לאפליקציות שלכם. כדי להתחיל כבר היום, אתם יכולים להשתמש בכלים שמתאימים לאפליקציה שלכם. לדוגמה, אתם יכולים להשתמש ב-Jetpack XR SDK כדי ליצור חוויות XR אימרסיביות באמצעות כלי פיתוח מודרניים ל-Android, כמו Kotlin ו-Compose.

בפוסט הזה בבלוג נספר על המסע שלנו להעברת הקסם של אפליקציית Androidify האהובה אל XR, ונסביר מה צריך לעשות כדי להעביר גם את האפליקציות שלכם אל XR.

סיור ב-Androidify

‫Androidify היא אפליקציה בקוד פתוח שמאפשרת ליצור בוטים של Android באמצעות חלק מהטכנולוגיות העדכניות ביותר, כמו Gemini,‏ CameraX,‏ Navigation 3 וכמובן Jetpack Compose. האפליקציה Androidify תוכננה במקור כך שתיראה נהדר בטלפונים, במכשירים מתקפלים ובטאבלטים, באמצעות יצירה של פריסות דינמיות.

customize.png

האפליקציה Androidify נראית מצוין במגוון גורמי צורה

אחד מעמודי התווך של פריסות מותאמות הוא רכיבים הניתנים לשימוש חוזר. ‫Jetpack Compose עוזר לכם ליצור רכיבי ממשק משתמש קטנים שאפשר לסדר בדרכים שונות כדי ליצור חוויות משתמש אינטואיטיביות, לא משנה באיזה סוג מכשיר המשתמש נמצא. למעשה, אפליקציית Androidify תואמת ל-Android XR ללא צורך בשינויים כלשהם באפליקציה.

customize_2.png

האפליקציה Androidify מותאמת ל-XR באמצעות פריסה רספונסיבית למסך גדול, ללא שינויים בקוד

אפליקציות שלא מותאמות במיוחד ל-Android XR יכולות לפעול במצב ריבוי משימות בחלון בגודל מתאים, והן פועלות בדומה לאופן שבו הן פועלות במסך גדול. לכן, אפליקציית Androidify כבר כוללת את כל התכונות ב-Android XR, בלי צורך בפעולות נוספות. אבל לא רצינו לעצור שם, אז החלטנו להתאמץ עוד יותר וליצור אפליקציה ייחודית ל-XR כדי לספק חוויה מהנה למשתמשי ה-XR שלנו.

התמצאות ב-XR

נתחיל עם מושגי יסוד מרכזיים ב-Android XR, החל משני המצבים שבהם אפשר להפעיל אפליקציות: מרחב הבית ומרחב מלא.

homespace.png
אפליקציות במרחב הבית
homespace2.png
אפליקציה במרחב מלא

במרחב הבית, אפשר להפעיל כמה אפליקציות זו לצד זו כדי שהמשתמשים יוכלו לבצע כמה משימות במקביל בחלונות שונים. במובן הזה, זה דומה מאוד לחלונות במחשב במכשיר Android עם מסך גדול, אבל במרחב וירטואלי!

במצב Full Space, לאפליקציה אין גבולות מרחביים והיא יכולה להשתמש בתכונות המרחביות המלאות של Android XR, כמו ממשק משתמש מרחבי ושליטה בסביבה הווירטואלית.

אולי תרצו שהאפליקציה תפעל רק במרחב מלא, אבל יכול להיות שהמשתמשים ירצו לבצע כמה משימות בו-זמנית באפליקציה, ולכן תמיכה בשני המצבים תאפשר חוויית משתמש טובה יותר.

עיצוב למימד החדש של Androidify

אפליקציה מעולה מתחילה בעיצוב נהדר. אייבי נייט (Ivy Knight), מומחית בכירה לעיצוב ב-Android DevRel, קיבלה על עצמה את המשימה של עיצוב חדש ל-XR על בסיס עיצובים קיימים של Androidify. תתחילי, אייבי!

התכנון למציאות מורחבת (XR) דרש גישה ייחודית, אבל למעשה היו לו הרבה נקודות משותפות עם תכנון לנייד. התחלנו לחשוב על הכלה: איך לארגן ולקבץ את רכיבי ממשק המשתמש במרחב המשנה, או על ידי הצגת גבולות ברורים או על ידי רמז עדין לגביהם. למדנו גם להשתמש בכל הגדלים השונים של רכיבי ממשק משתמש מרחביים, שנועדו להשתנות ולזוז בתגובה למשתמש. כמו שעשינו ב-Androidify, בונים עם פריסות דינמיות, כדי שתוכלו לחלק את הפריסות לחלקים עבור ממשק המשתמש המרחבי.

איך מתחילים לעצב עם המרחב הביתי

למזלנו, Android XR מאפשר לכם להתחיל עם האפליקציה שלכם כמו שהיא היום במרחב הבית, כך שתוכלו לעבור לעיצובים המורחבים של XR על ידי הוספה של סרגל כלים לחלון ולחצן מעבר למסך מלא.

בנוסף, בחנו תכונות אפשריות של חומרה ואיך המשתמש יקיים איתן אינטראקציה. הפריסות לנייד ב-Androidify מותאמות למצבים שונים, לגדלים שונים של כיתות ולמספר המצלמות, כדי לספק יותר אפשרויות לצילום. בהתאם למודל הזה, היינו צריכים להתאים את פריסת המצלמה גם למכשירי אוזניות. היינו צריכים גם לבצע שינויים בטקסט כדי שיתאים למיקום של ממשק המשתמש ביחס למשתמש.

תכנון לקראת המעבר הגדול יותר למצב 'מרחב מלא'

השינוי הכי גדול היה במרחב המלא, אבל הוא גם אפשר לנו הכי הרבה חופש יצירתי להתאים את העיצוב. 

tablet_to_xr.webp
מטאבלט ל-XR

‫Androidify משתמש בתיבות או בחלוניות כדי לקבץ תכונות עם רקע וקו מתאר, כמו החלונית 'צילום או בחירת תמונה'. השתמשנו גם ברכיבים כמו סרגל האפליקציות העליון כדי ליצור הכלה טבעית על ידי מסגור של החלוניות האחרות. לבסוף, הקרבה של רכיבים מסוימים לרכיבים אחרים, כמו הלחצן "התחלת השינוי" בתחתית, שנמצא ליד החלונית "בחירת צבע הבוט שלי", מרמזת על הכלה פנימית.

חלוניות מרחביות שנועדו להפרדה קלה. כדי להחליט איך להתאים את העיצובים לנייד ללוחות מרחביים, נסו להסיר משטחים החל מהמשטח הכי אחורי ואז להתקדם קדימה. כדאי לנסות להסיר כמה רקעים ולראות מה נשאר. אחרי שביצענו את התרגיל הזה ב-Androidify, מה שנשאר היה הקו הירוק הגדול של Android. הקו המתפתל לא שימש רק כרקע וכאלמנט מיתוג, אלא גם כעוגן לתוכן במרחב תלת-ממדי.

הגדרת העוגן הזה הקלה על הדמיון של תנועת הרכיבים סביבו, ועל האופן שבו אפשר להשתמש בקרבה כדי להפריד ולתרגם את שאר חוויית המשתמש.

טיפים נוספים לעיצוב שיעזרו לכם להוסיף לאפליקציה תכונות מרחביות

  • לא להגביל את הרכיבים: אפשר להוציא רכיבים מהקופסה ולתת להם קצת מקום אמיתי (מרחבי). הגיע הזמן לתת לרכיבי ממשק המשתמש האלה קצת מרווח נשימה.
  • הסרת משטחים: הסתרת הרקע כדי לראות איך זה משפיע על העיצובים.
  • מעוררים מוטיבציה באמצעות תנועה: איך אתם משתמשים במעברים באפליקציה? תשתמשו בדמות הזו כדי לדמיין את האפליקציה שלכם פורצת אל תוך ה-VR.
  • בחירת עוגן: כדי שהמשתמשים לא יאבדו את עצמם במרחב. יש רכיב שעוזר לאסוף או לבסס את ממשק המשתמש.

מידע נוסף על דפוסי עיצוב של ממשקי משתמש ב-XR זמין במאמר עיצוב ל-Android XR ב-Android Developers.

יסודות של ממשק משתמש מרחבי

אחרי שראינו איך אייבי התאימה את הגישה שלה בזמן עיצוב Androidify ל-XR, נדבר על פיתוח ממשק משתמש מרחבי. אם אתם רגילים לעבוד עם כלים וספריות מודרניים של Android, פיתוח ממשק משתמש מרחבי באמצעות Jetpack XR SDK אמור להיראות לכם מוכר. תמצאו מושגים שאתם כבר מכירים, כמו יצירת פריסות באמצעות Compose. למעשה, פריסות מרחביות דומות מאוד לפריסות דו-ממדיות שמשתמשות בשורות, בעמודות וברווחים:

spatialrows.png

הרכיבים האלה מסודרים ב- SpatialRows וב- SpatialColumns

הרכיבים המרחביים שמוצגים כאן הם רכיבים הניתנים להרכבה מסוג SpatialPanel, שמאפשרים להציג תוכן דו-ממדי כמו טקסט, לחצנים וסרטונים.

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

‫SpatialPanel הוא subspace composable. רכיבי Subspace composable חייבים להיכלל ב-Subspace, והם משתנים על ידי אובייקטים מסוג SubspaceModifier. אפשר למקם את רכיבי ה-Subspace בכל מקום בהיררכיית ממשק המשתמש של האפליקציה, והם יכולים להכיל רק רכיבי Subspace שניתנים להרכבה. אובייקטים מסוג SubspaceModifier דומים מאוד לאובייקטים מסוג Modifier: הם שולטים בפרמטרים כמו גודל ומיקום.

אפשר לצרף Orbiter ל-SpatialPanel ולהעביר אותו יחד עם התוכן שהוא מצורף אליו. הם משמשים בדרך כלל כדי לספק אמצעי בקרה הקשריים לגבי התוכן שאליהם הם מצורפים, כך שהתוכן הוא המוקד העיקרי. אפשר למקם אותן בכל אחד מארבעת הצדדים של התוכן, במרחק שניתן להגדרה.

orbiter.png
מכשיר Orbiter מחובר לחלק התחתון של SpatialPanel

יש עוד הרבה אלמנטים בממשק המשתמש המרחבי, אבל אלה העיקריים שבהם השתמשנו כדי ליצור פריסות מרחביות ל-Androidify.

איך מתחילים לפתח תוכן ל-XR

נתחיל בהגדרת הפרויקט. הוספנו את התלות ב-Jetpack XR Compose, שאפשר למצוא בדף Jetpack XR dependencies.

הוספנו קוד ללחצן שמעביר את המשתמש למרחב מלא, ומתחיל בזיהוי היכולת לעשות זאת:

@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"),
       )
   }
}

עכשיו, כשלוחצים על הכפתור הזה, הפריסה הבינונית מוצגת במרחב מלא. אנחנו יכולים לבדוק את היכולות המרחביות ולקבוע אם אפשר להציג ממשק משתמש מרחבי – במקרה כזה, נציג את הפריסה המרחבית החדשה שלנו במקום:

@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

זיהינו כאן שני רכיבי SpatialPanel: חלונית אחת שכרטיס הווידאו נמצא בה בצד שמאל, וחלונית אחת שמכילה את ממשק המשתמש הראשי. לבסוף, בחלק העליון מחובר Orbiter. נתחיל עם החלונית של נגן הווידאו:

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

פשוט השתמשנו מחדש ברכיב 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
מסך היצירה במרחב מלא

כאן השתמשנו ברכיבי ה-Composable‏ SpatialRow ו-SpatialColumn כדי ליצור פריסה שמתאימה למרחב הצפייה המומלץ, ושוב השתמשנו ברכיבים מהפריסה Medium.

fullspace_2.png

מסך תוצאות במרחב מלא: בוט שנוצר באמצעות הנחיה: כובע בייסבול אדום, משקפי טייסים, חולצת טי בצבע כחול בהיר, מכנסיים קצרים עם משבצות אדומות ולבנות, כפכפים ירוקים ומחבט טניס.


במסך התוצאות מוצגים הציטוטים המשלימים עם אפקט טשטוש, כך שהם נעלמים בהדרגה ליד הקצוות של המסך. בנוסף, כשצופים בקלט שבו נעשה שימוש, המערכת משתמשת במעבר תלת-ממדי אמיתי, והתמונה מתהפכת במרחב.

פרסום בחנות Google Play

אחרי שהאפליקציה הייתה מוכנה ל-XR עם פריסות מרחביות, המשכנו לפרסם אותה בחנות 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" />

כך חנות Play יודעת שהאפליקציה הזו כוללת תכונות ייחודיות ל-XR, ומציגה תג שמאפשר למשתמשים לדעת שהאפליקציה נוצרה תוך מחשבה על XR:

androidify2.png
Androidify כפי שמופיע בחנות Google Play ב-Android XR


כשמעלים את הגרסה, לא צריך לבצע שלבים מיוחדים כדי לפרסם אותה למכשירי XR: אותה אפליקציה מופצת כרגיל למשתמשים במסלול לנייד ולמשתמשים במכשיר XR. עם זאת, אתם יכולים להוסיף צילומי מסך ספציפיים ל-XR של האפליקציה שלכם, או אפילו להעלות תצוגה מקדימה סוחפת של האפליקציה באמצעות נכס וידאו מרחבי. במכשירי Android XR, חנות Play מציגה את התוכן הזה באופן אוטומטי כתצוגה מקדימה תלת-ממדית סוחפת, וכך המשתמשים יכולים לחוות את העומק וההיקף של התוכן לפני שהם מתקינים את האפליקציה.

מתחילים ליצור חוויות משלכם עוד היום

‫Androidify היא דוגמה מצוינת לאופן שבו אפשר להפוך אפליקציה קיימת של Jetpack Compose דו-ממדית לאפליקציה תלת-ממדית. היום הצגנו את התהליך המלא של פיתוח ממשק משתמש תלת-ממדי ל-Androidify, החל מהעיצוב, דרך הקוד ועד לפרסום. שינינו את העיצובים הקיימים כך שיתאימו לפרדיגמות מרחביות, השתמשנו ברכיבי SpatialPanel ו-Orbiter כדי ליצור פריסות מרחביות שמוצגות כשהמשתמש נכנס למצב 'מרחב מלא', ולבסוף פרסמנו את הגרסה החדשה של האפליקציה בחנות Play.

אנחנו מקווים שהפוסט הזה בבלוג עזר לכם להבין איך אפשר להביא את האפליקציות שלכם ל-Android XR. הנה עוד כמה קישורים שיכולים לעזור לך:

נכתב על ידי:

להמשך הקריאה