מדריכים

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

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

‫Samsung Galaxy XR כבר כאן, והוא מבוסס על Android XR! הפוסט הזה בבלוג הוא חלק מ שבוע Android XR Spotlight, שבו אנחנו מספקים משאבים – פוסטים בבלוג, סרטונים, קוד לדוגמה ועוד – שנועדו לעזור לכם ללמוד, ליצור ולהכין את האפליקציות שלכם ל-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 פיתוח נייטיב. האפליקציה Androidify תוכננה במקור כך שתיראה נהדר בטלפונים, במכשירים מתקפלים ובטאבלטים, באמצעות יצירה של פריסות דינמיות.

customize.png

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

אחד מעמודי התווך של פריסות מותאמות הוא רכיבים הניתנים לשימוש חוזר. ‫Jetpack פיתוח נייטיב עוזר לכם ליצור רכיבי ממשק משתמש קטנים שאפשר לסדר בדרכים שונות כדי ליצור חוויות משתמש אינטואיטיביות, לא משנה באיזה סוג מכשיר המשתמש משתמש. למעשה, אפליקציית 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, בונים עם פריסות דינמיות, כדי שתוכלו לחלק את הפריסות לחלקים עבור ממשק המשתמש המרחבי.

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

למזלנו, 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. רכיבים של תת-מרחב חייבים להיות כלולים בתת-מרחב, והם משתנים על ידי אובייקטים של SubspaceModifier. אפשר למקם את רכיבי ה-Subspace בכל מקום בהיררכיית ממשק המשתמש של האפליקציה, והם יכולים להכיל רק רכיבי Subspace. אובייקטים של SubspaceModifier דומים מאוד לאובייקטים של Modifier: הם שולטים בפרמטרים כמו גודל ומיקום.

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

orbiter.png
An Orbiter is attached to the bottom of a 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 פיתוח נייטיב דו-ממדית לאפליקציה תלת-ממדית. היום הצגנו את התהליך המלא של פיתוח ממשק משתמש תלת-ממדי ל-Androidify, החל מהעיצוב ועד לקוד ולפרסום. שינינו את העיצובים הקיימים כדי שיתאימו לפרדיגמות מרחביות, השתמשנו ברכיבים הניתנים להרכבה SpatialPanel ו-Orbiter כדי ליצור פריסות מרחביות שמוצגות כשהמשתמש נכנס למצב 'מרחב מלא', ולבסוף פרסמנו את הגרסה החדשה של האפליקציה בחנות Play.

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

נכתב על ידי:

להמשך הקריאה