توسعه رابط کاربری با Jetpack Compose برای XR

با Jetpack Compose برای XR، می‌توانید رابط کاربری و طرح‌بندی فضایی خود را با استفاده از مفاهیم آشنای Compose مانند سطرها و ستون‌ها به‌طور آشکار بسازید. این به شما امکان می دهد رابط کاربری اندروید موجود خود را به فضای سه بعدی گسترش دهید یا برنامه های سه بعدی همهجانبه کاملاً جدیدی بسازید.

اگر یک برنامه موجود مبتنی بر Views اندروید را فضایی می کنید، چندین گزینه توسعه دارید. می‌توانید از APIهای قابلیت همکاری استفاده کنید، از Compose و Views با هم استفاده کنید یا مستقیماً با کتابخانه SceneCore کار کنید. برای جزئیات بیشتر به راهنمای ما برای کار با نماها مراجعه کنید.

درباره فضاهای فرعی و اجزای فضایی

هنگامی که برنامه خود را برای Android XR می نویسید، درک مفاهیم زیرفضا و اجزای فضایی بسیار مهم است.

درباره زیرفضا

هنگام توسعه برای Android XR، باید یک فضای فرعی به برنامه یا طرح‌بندی خود اضافه کنید. فضای فرعی پارتیشنی از فضای سه بعدی در برنامه شما است که می توانید محتوای سه بعدی را قرار دهید، طرح بندی های سه بعدی بسازید و به محتوای دو بعدی در غیر این صورت عمق دهید. یک فضای فرعی تنها زمانی ارائه می شود که فضایی سازی فعال باشد. در Home Space یا در دستگاه‌های غیر XR، هر کدی در آن زیرفضا نادیده گرفته می‌شود.

دو راه برای ایجاد زیرفضا وجود دارد:

  • setSubspaceContent : این تابع یک زیرفضای سطح برنامه ایجاد می کند. این را می توان در MainActivity شما به همان روشی که از setContent استفاده می کنید فراخوانی کرد. یک زیرفضای سطح برنامه از نظر ارتفاع، عرض و عمق نامحدود است و اساساً یک بوم بی‌نهایت برای محتوای فضایی فراهم می‌کند.
  • Subspace : این قابل ترکیب را می توان در هر جایی در سلسله مراتب UI برنامه شما قرار داد، به شما این امکان را می دهد که طرح بندی ها را برای UI دو بعدی و فضایی بدون از دست دادن زمینه بین فایل ها حفظ کنید. این کار اشتراک‌گذاری مواردی مانند معماری برنامه‌های موجود بین XR و سایر فاکتورهای شکل را بدون نیاز به بالا بردن حالت در کل درخت رابط کاربری یا معماری مجدد برنامه‌تان آسان‌تر می‌کند.

برای اطلاعات بیشتر، درباره افزودن یک فضای فرعی به برنامه خود بخوانید.

درباره اجزای فضایی

زیرفضاهای composable : این مولفه‌ها فقط در یک زیرفضا قابل ارائه هستند. آنها باید قبل از قرار گرفتن در یک طرح دو بعدی در Subspace یا setSubspaceContent محصور شوند. یک SubspaceModifier به شما امکان می‌دهد ویژگی‌هایی مانند عمق، افست و موقعیت‌یابی را به زیرفضای composable خود اضافه کنید.

  • نکته در مورد اصلاح‌کننده‌های زیرفضا : به ترتیب APIهای SubspaceModifier دقت کنید.
    • آفست باید ابتدا در یک زنجیره اصلاح کننده رخ دهد
    • متحرک و قابل تغییر اندازه باید در آخر اتفاق بیفتد
    • چرخش باید قبل از مقیاس اعمال شود

سایر اجزای فضایی نیازی به فراخوانی در یک زیرفضا ندارند. آنها از عناصر دو بعدی معمولی تشکیل شده اند که در یک ظرف فضایی پیچیده شده اند. اگر برای هر دو تعریف شده باشد، می توان از این عناصر در طرح بندی های دو بعدی یا سه بعدی استفاده کرد. وقتی فضایی‌سازی فعال نباشد، ویژگی‌های فضایی آن‌ها نادیده گرفته می‌شود و به همتایان دوبعدی خود بازمی‌گردند.

یک پانل فضایی ایجاد کنید

SpatialPanel یک فضای فرعی قابل ترکیب است که به شما امکان می دهد محتوای برنامه را نمایش دهید – برای مثال، می توانید پخش ویدیو، تصاویر ثابت یا هر محتوای دیگری را در یک پانل فضایی نمایش دهید.

نمونه ای از پانل UI فضایی

همانطور که در مثال زیر نشان داده شده است می توانید از SubspaceModifier برای تغییر اندازه، رفتار و موقعیت پانل فضایی استفاده کنید.

Subspace {
   SpatialPanel(
        SubspaceModifier
           .height(824.dp)
           .width(1400.dp)
           .movable()
           .resizable()
           ) {
          SpatialPanelContent()
      }
}

// 2D content placed within the spatial panel
@Composable
fun SpatialPanelContent(){
    Box(
        Modifier
            .background(color = Color.Black)
            .height(500.dp)
            .width(500.dp),
        contentAlignment = Alignment.Center
    ) {
        Text(
            text = "Spatial Panel",
            color = Color.White,
            fontSize = 25.sp
        )
    }
}

نکات کلیدی در مورد کد

  • نکته در مورد اصلاح‌کننده‌های زیرفضا : به ترتیب APIهای SubspaceModifier دقت کنید.
    • آفست باید ابتدا در یک زنجیره اصلاح کننده رخ دهد.
    • اصلاح‌کننده‌های متحرک و قابل تغییر اندازه باید در آخر اتفاق بیفتند.
    • چرخش باید قبل از مقیاس اعمال شود.
  • از آنجایی که SpatialPanel APIهای زیرفضایی قابل ترکیب هستند، باید آنها را در Subspace یا setSubspaceContent فراخوانی کنید. فراخوانی آنها در خارج از یک فضای فرعی یک استثنا ایجاد می کند.
  • با افزودن .movable یا .resizable SubspaceModifier s به کاربر اجازه تغییر اندازه یا حرکت پانل را بدهید.
  • برای جزئیات در مورد اندازه و موقعیت به راهنمای طراحی پانل فضایی ما مراجعه کنید. برای جزئیات بیشتر در مورد اجرای کد به مستندات مرجع ما مراجعه کنید.

یک مدارگرد ایجاد کنید

مدارگرد یک جزء رابط کاربری فضایی است. طراحی شده است تا به یک پانل فضایی مربوطه متصل شود و شامل موارد ناوبری و کنش متنی مربوط به آن پانل فضایی است. برای مثال، اگر یک پانل فضایی برای نمایش محتوای ویدیویی ایجاد کرده‌اید، می‌توانید کنترل‌های پخش ویدیو را در یک مدارگرد اضافه کنید.

نمونه ای از مدارگرد

همانطور که در مثال زیر نشان داده شده است، یک مدارگرد را در داخل SpatialPanel فراخوانی کنید تا کنترل‌های کاربر مانند ناوبری را بپیچد. با انجام این کار آنها را از چیدمان دوبعدی شما استخراج کرده و با توجه به پیکربندی شما به پانل فضایی متصل می کند.

setContent {
    Subspace {
        SpatialPanel(
            SubspaceModifier
                .height(824.dp)
                .width(1400.dp)
                .movable()
                .resizable()
        ) {
            SpatialPanelContent()
            OrbiterExample()
        }
    }
}

//2D content inside Orbiter
@Composable
fun OrbiterExample() {
    Orbiter(
        position = OrbiterEdge.Bottom,
        offset = 96.dp,
        alignment = Alignment.CenterHorizontally
    ) {
        Surface(Modifier.clip(CircleShape)) {
            Row(
                Modifier
                    .background(color = Color.Black)
                    .height(100.dp)
                    .width(600.dp),
                horizontalArrangement = Arrangement.Center,
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(
                    text = "Orbiter",
                    color = Color.White,
                    fontSize = 50.sp
                )
            }
        }
    }
}

نکات کلیدی در مورد کد

  • نکته در مورد Subspace Modifier : به ترتیب APIهای SubspaceModifier دقت کنید.
    • آفست باید ابتدا در یک زنجیره اصلاح کننده رخ دهد
    • متحرک و قابل تغییر اندازه باید در آخر اتفاق بیفتد
    • چرخش باید قبل از مقیاس اعمال شود
  • از آنجا که مدارگردها اجزای رابط کاربری فضایی هستند، کد را می توان در طرح‌بندی‌های دو بعدی یا سه بعدی استفاده کرد. در یک طرح دو بعدی، برنامه شما فقط محتوای داخل مدارگرد را رندر می کند و خود مدارگرد را نادیده می گیرد.
  • برای اطلاعات بیشتر در مورد نحوه استفاده و طراحی مدارگردها، راهنمای طراحی ما را بررسی کنید.

چند پانل فضایی را به یک طرح فضایی اضافه کنید

شما می توانید چندین پانل فضایی ایجاد کنید و با استفاده از SpatialRow ، SpatialColumn ، SpatialBox و SpatialLayoutSpacer آنها را در یک SpatialLayout قرار دهید.

نمونه ای از چند پانل فضایی در یک طرح فضایی

مثال کد زیر نحوه انجام این کار را نشان می دهد.

Subspace {
    SpatialRow {
        SpatialColumn {
            SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
                SpatialPanelContent("Top Left")
            }
            SpatialPanel(SubspaceModifier.height(200.dp).width(400.dp)) {
                SpatialPanelContent("Middle Left")
            }
            SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
                SpatialPanelContent("Bottom Left")
            }
        }
        SpatialColumn {
            SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
                SpatialPanelContent("Top Right")
            }
            SpatialPanel(SubspaceModifier.height(200.dp).width(400.dp)) {
                SpatialPanelContent("Middle Right")
            }
            SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
                SpatialPanelContent("Bottom Right")
            }
        }
    }
}

@Composable
fun SpatialPanelContent(text: String) {
    Column(
        Modifier
            .background(color = Color.Black)
            .fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(
            text = "Panel",
            color = Color.White,
            fontSize = 15.sp
        )
        Text(
            text = text,
            color = Color.White,
            fontSize = 25.sp,
            fontWeight = FontWeight.Bold
        )
    }
}

نکات کلیدی در مورد کد

  • SpatialRow ، SpatialColumn ، SpatialBox ، و SpatialLayoutSpacer همگی زیرفضای قابل ترکیب هستند و باید در یک زیرفضا قرار گیرند.
  • از SubspaceModifier برای سفارشی کردن طرح خود استفاده کنید.
  • برای طرح‌بندی‌هایی با چند پانل پشت سر هم، توصیه می‌کنیم شعاع منحنی 825dp را با استفاده از SubspaceModifier تنظیم کنید تا پانل‌ها کاربر شما را احاطه کنند. برای جزئیات به راهنمای طراحی ما مراجعه کنید.

از یک حجم برای قرار دادن یک شی 3 بعدی در طرح خود استفاده کنید

برای قرار دادن یک شی سه بعدی در چیدمان خود، باید از یک فضای فرعی به نام حجم استفاده کنید. در اینجا مثالی از نحوه انجام این کار آورده شده است.

نمونه ای از یک شی سه بعدی در یک طرح

Subspace {
    SpatialPanel(
        SubspaceModifier.height(1500.dp).width(1500.dp)
            .resizable().movable()
    ) {
        ObjectInAVolume(true)
            Box(
                Modifier.fillMaxSize(),
                contentAlignment = Alignment.Center
            ) {
                Text(
                    text = "Welcome",
                    fontSize = 50.sp,
                )
            }
        }
    }
}

@Composable
fun ObjectInAVolume(show3DObject: Boolean) {
    val xrCoreSession = checkNotNull(LocalSession.current)
    val scope = rememberCoroutineScope()
    if (show3DObject) {
        Subspace {
            Volume(
                modifier = SubspaceModifier
                    .offset(volumeXOffset, volumeYOffset, volumeZOffset) //
Relative position
                    .scale(1.2f) // Scale to 120% of the size

            ) { parent ->
                scope.launch {
                   // Load your 3D Object here
                }
            }
        }
    }
}

نکات کلیدی در مورد کد

  • نکته در مورد Subspace Modifier : به ترتیب APIهای SubspaceModifier دقت کنید.
    • آفست باید ابتدا در یک زنجیره اصلاح کننده رخ دهد
    • متحرک و قابل تغییر اندازه باید در آخر اتفاق بیفتد
    • چرخش باید قبل از مقیاس اعمال شود
  • برای درک بهتر نحوه بارگیری محتوای سه بعدی در یک حجم، به افزودن محتوای سه بعدی مراجعه کنید.

سایر اجزای رابط کاربری فضایی را اضافه کنید

اجزای فضایی UI را می توان در هر نقطه از سلسله مراتب UI برنامه شما قرار داد. این عناصر را می‌توان در رابط کاربری دوبعدی شما استفاده مجدد کرد و ویژگی‌های فضایی آنها تنها زمانی قابل مشاهده خواهند بود که قابلیت‌های فضایی فعال باشند. این به شما امکان می دهد بدون نیاز به دوبار نوشتن کد خود، ارتفاع را به منوها، دیالوگ ها و سایر اجزاء اضافه کنید. برای درک بهتر نحوه استفاده از این عناصر، نمونه‌های زیر از رابط کاربری فضایی را ببینید.

کامپوننت UI

وقتی فضایی سازی فعال است

در محیط دو بعدی

SpatialDialog

پانل کمی به عقب در عمق z فشار می آورد تا یک گفتگوی بالا را نمایش دهد

به Dialog دوبعدی باز می گردد.

SpatialPopUp

پانل کمی به عقب در عمق z فشار می آورد تا یک پنجره بازشوی بالا نمایش داده شود

به یک PopUp دوبعدی برمی گردد.

SpatialElevation

SpatialElevationLevel می توان برای اضافه کردن ارتفاع تنظیم کرد.

نمایش بدون ارتفاع مکانی.

فضایی دیالوگ

این نمونه ای از گفتگو است که پس از یک تاخیر کوتاه باز می شود. هنگامی که از SpatialDialog استفاده می شود، گفتگو در همان عمق z مانند پانل فضایی ظاهر می شود، و پانل با 125dp به عقب رانده می شود زمانی که فضایی سازی فعال است. SpatialDialog همچنان می‌تواند استفاده شود که فضایی‌سازی نیز فعال نباشد، و به همتای دوبعدی خود باز می‌گردد: Dialog .

@Composable
fun DelayedDialog() {
   var showDialog by remember { mutableStateOf(false) }
   LaunchedEffect(Unit) {
       Handler(Looper.getMainLooper()).postDelayed({
           showDialog = true
       }, 3000)
   }
   if (showDialog) {
       SpatialDialog (
           onDismissRequest = { showDialog = false },
           SpatialDialogProperties(
               dismissOnBackPress = true)
       ){
           Box(Modifier
               .height(150.dp)
               .width(150.dp)
           ) {
               Button(onClick = { showDialog = false }) {
                   Text("OK")
               }
           }
       }
   }
}

نکات کلیدی در مورد کد

پانل ها و طرح بندی های سفارشی ایجاد کنید

برای ایجاد پنل‌های سفارشی که توسط Compose برای XR پشتیبانی نمی‌شوند، می‌توانید مستقیماً با PanelEntities و نمودار صحنه با استفاده از APIهای SceneCore کار کنید.

همچنین ببینید