מדריכים

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

משך הקריאה: 9 דקות
הצגת הפרופיל של Dereck Bridie
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 עם מסך גדול, אבל במרחב וירטואלי!

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

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

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

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

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

איך מתחילים לעצב עם Home Space

למזלנו, 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
מסך היצירה במרחב מלא

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

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. הנה עוד כמה קישורים שיכולים לעזור לך:

נכתב על ידי:
המשך קריאה