XR için Jetpack Compose ile satır ve sütun gibi bilinen Compose kavramlarını kullanarak uzamsal kullanıcı arayüzünüzü ve düzeninizi açık bir şekilde oluşturabilirsiniz. Bu sayede mevcut Android kullanıcı arayüzünüzü 3D alana genişletebilir veya tamamen yeni, sürükleyici 3D uygulamalar oluşturabilirsiniz.
Mevcut bir Android Views tabanlı uygulamayı mekansallaştırıyorsanız birkaç geliştirme seçeneğiniz vardır. Birlikte çalışabilirlik API'lerini, Compose ve Views'ı birlikte kullanabilir veya doğrudan SceneCore kitaplığıyla çalışabilirsiniz. Daha fazla bilgi için görüntülemelerle çalışma kılavuzumuzu inceleyin.
Alt alanlar ve uzamsal bileşenler hakkında
Android XR için uygulamanızı yazarken alt alan ve uzamsallaştırılmış bileşenler kavramlarını anlamanız önemlidir.
Alt alan hakkında
Android XR için geliştirirken uygulamanıza veya düzeninize bir alt alan eklemeniz gerekir. Alt alan, uygulamanızda 3D içerik yerleştirebileceğiniz, 3D düzenler oluşturabileceğiniz ve aksi takdirde 2D olan içeriğe derinlik ekleyebileceğiniz 3D alanın bir bölümüdür. Alt alan yalnızca uzamsallaştırma etkinleştirildiğinde oluşturulur. Ana mekanda veya XR olmayan cihazlarda, bu alt alan içindeki tüm kodlar yoksayılır.
Alt alan oluşturmanın iki yolu vardır:
setSubspaceContent()
: Bu işlev, uygulama düzeyinde bir alt alan oluşturur. Bu, ana etkinliğinizdesetContent()
'u kullandığınız şekilde çağrılabilir. Uygulama düzeyinde alt uzay, yükseklik, genişlik ve derinlik açısından sınırsızdır. Bu sayede, uzamsal içerik için sonsuz bir tuval sağlar.Subspace
: Bu bileşen, uygulamanızın kullanıcı arayüzü hiyerarşisinin herhangi bir yerine yerleştirilebilir. Böylece, dosyalar arasındaki bağlamı kaybetmeden 2D ve mekansal kullanıcı arayüzü için düzenleri koruyabilirsiniz. Bu sayede, kullanıcı arayüzü ağacınızın tamamında durumu kaldırmak veya uygulamanızı yeniden tasarlamak zorunda kalmadan mevcut uygulama mimarisi gibi öğeleri XR ile diğer form faktörleri arasında paylaşabilirsiniz.
Daha fazla bilgi için Uygulamanıza alt alan adı ekleme başlıklı makaleyi inceleyin.
Mekansal bileşenler hakkında
Alt alan bileşenleri: Bu bileşenler yalnızca bir alt alanda oluşturulabilir.
2D bir düzene yerleştirilmeden önce Subspace
veya setSubspaceContent
içine alınmalıdır. SubspaceModifier
, alt alan bileşimlerinize derinlik, ofset ve konumlandırma gibi özellikler eklemenize olanak tanır.
Diğer uzamsal bileşenlerin bir alt uzayda çağrılması gerekmez. Bunlar, bir mekansal kapsayıcıya yerleştirilmiş geleneksel 2D öğelerden oluşur. Bu öğeler, her ikisi için de tanımlanmışsa 2D veya 3D düzenlerde kullanılabilir. Mekansallaştırma etkinleştirilmediğinde, bu öğelerin mekansallaştırılmış özellikleri yoksayılır ve 2D karşılıklarına geri dönerler.
Mekansal panel oluşturma
SpatialPanel
, uygulama içeriğini görüntülemenize olanak tanıyan bir alt alan bileşimidir. Örneğin, video oynatma, hareketsiz resimler veya diğer içerikleri bir uzamsal panelde görüntüleyebilirsiniz.
Aşağıdaki örnekte gösterildiği gibi, SubspaceModifier
simgesini kullanarak mekansal panelin boyutunu, davranışını ve konumunu değiştirebilirsiniz.
Subspace { SpatialPanel( SubspaceModifier .height(824.dp) .width(1400.dp) .movable() .resizable() ) { SpatialPanelContent() } }
@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 ) } }
Kodla ilgili önemli noktalar
SpatialPanel
API'leri alt alan kompozitleri olduğundan bunlarıSubspace
veyasetSubspaceContent
içinde çağırmanız gerekir. Bu işlevler, alt alan dışında çağrılırsa istisna atılır.movable
veyaresizable
değiştiricileri ekleyerek kullanıcının paneli yeniden boyutlandırmasına ya da taşımasına izin verin.- Boyut ve konumlandırmayla ilgili ayrıntılar için uzamsal panel tasarımı yönergelerimize göz atın. Kod uygulamayla ilgili daha fazla bilgi için referans dokümanlarımızı inceleyin.
Hareketli alt alan değiştiricinin işleyiş şekli
Kullanıcı bir paneli kendisinden uzaklaştırırken varsayılan olarak taşınabilir alt alan değiştirici, paneli ana alanda panellerin sistem tarafından yeniden boyutlandırılmasına benzer şekilde ölçeklendirir. Tüm çocuk içerikleri bu davranışı devralır. Bunu devre dışı bırakmak için scaleWithDistance
parametresini false
olarak ayarlayın.
Yörünge aracı oluşturma
Yörünge, mekansal bir kullanıcı arayüzü bileşenidir. İlgili bir mekansal panele, düzene veya başka bir öğeye eklenecek şekilde tasarlanmıştır. Yörüngeleyiciler genellikle sabitlendiği öğeyle ilgili gezinme ve bağlamsal işlem öğeleri içerir. Örneğin, video içeriği görüntülemek için bir uzamsal panel oluşturduysanız bir yörünge aracının içine video oynatma kontrolleri ekleyebilirsiniz.
Aşağıdaki örnekte gösterildiği gibi, gezinme gibi kullanıcı denetimlerini sarmalamak için SpatialPanel
içinde 2D düzenin içine bir yörünge çağrısı yapın. Bu işlem, öğeleri 2D düzeninizden ayıklayıp yapılandırmanıza göre mekansal panele ekler.
Subspace { SpatialPanel( SubspaceModifier .height(824.dp) .width(1400.dp) .movable() .resizable() ) { SpatialPanelContent() OrbiterExample() } }
@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 ) } } } }
Kodla ilgili önemli noktalar
- Yörünge bileşenleri, mekansal kullanıcı arayüzü bileşenleri olduğundan kod 2D veya 3D düzenlerde yeniden kullanılabilir. 2D düzende uygulamanız yalnızca yörünge aracının içindeki içeriği oluşturur ve yörünge aracının kendisini yoksayar.
- Yörünge araçlarını kullanma ve tasarlama hakkında daha fazla bilgi için tasarım yönergelerimize göz atın.
Mekansal bir düzene birden fazla mekansal panel ekleme
SpatialRow
, SpatialColumn
, SpatialBox
ve SpatialLayoutSpacer
simgesini kullanarak birden fazla mekansal panel oluşturabilir ve bunları bir mekansal düzene yerleştirebilirsiniz.
Aşağıdaki kod örneğinde bunun nasıl yapılacağı gösterilmektedir.
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 ) } }
Kodla ilgili önemli noktalar
SpatialRow
,SpatialColumn
,SpatialBox
veSpatialLayoutSpacer
hepsi alt alan bileşenidir ve bir alt alana yerleştirilmelidir.- Düzeninizi özelleştirmek için
SubspaceModifier
simgesini kullanın. - Bir satırda birden fazla panel bulunan düzenler için panellerin kullanıcınızı çevrelemesi amacıyla
SubspaceModifier
kullanarak 825 dp'lik bir eğri yarıçapı ayarlamanızı öneririz. Ayrıntılar için tasarım yönergelerimize bakın.
Düzeninize 3D nesne yerleştirmek için bir birim kullanın
Bir 3D nesneyi düzeninize yerleştirmek için hacim adı verilen bir alt alan bileşimi kullanmanız gerekir. Aşağıda bunu nasıl yapacağınıza dair bir örnek verilmiştir.
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) {
Ek bilgiler
- Bir birime 3D içeriğin nasıl yükleneceğini daha iyi anlamak için Uygulamanıza 3D model ekleme başlıklı makaleyi inceleyin.
Resim veya video içeriği için bir yüzey ekleme
SpatialExternalSurface
, uygulamanızın resim veya video gibi içerikler çizebileceği Surface
'i oluşturan ve yöneten bir alt alan bileşimidir. SpatialExternalSurface
stereoskopik veya monoskopik içerikleri destekler.
Bu örnekte, Media3 Exoplayer ve SpatialExternalSurface
kullanılarak yan yana stereoskopik videonun nasıl yükleneceği gösterilmektedir:
@Composable fun SpatialExternalSurfaceContent() { val context = LocalContext.current Subspace { SpatialExternalSurface( modifier = SubspaceModifier .width(1200.dp) // Default width is 400.dp if no width modifier is specified .height(676.dp), // Default height is 400.dp if no height modifier is specified // Use StereoMode.Mono, StereoMode.SideBySide, or StereoMode.TopBottom, depending // upon which type of content you are rendering: monoscopic content, side-by-side stereo // content, or top-bottom stereo content stereoMode = StereoMode.SideBySide, ) { val exoPlayer = remember { ExoPlayer.Builder(context).build() } val videoUri = Uri.Builder() .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) // Represents a side-by-side stereo video, where each frame contains a pair of // video frames arranged side-by-side. The frame on the left represents the left // eye view, and the frame on the right represents the right eye view. .path("sbs_video.mp4") .build() val mediaItem = MediaItem.fromUri(videoUri) // onSurfaceCreated is invoked only one time, when the Surface is created onSurfaceCreated { surface -> exoPlayer.setVideoSurface(surface) exoPlayer.setMediaItem(mediaItem) exoPlayer.prepare() exoPlayer.play() } // onSurfaceDestroyed is invoked when the SpatialExternalSurface composable and its // associated Surface are destroyed onSurfaceDestroyed { exoPlayer.release() } } } }
Kodla ilgili önemli noktalar
- Oluşturduğunuz içerik türüne bağlı olarak
StereoMode
değeriniMono
,SideBySide
veyaTopBottom
olarak ayarlayın:Mono
: Resim veya video karesi, her iki göze de gösterilen tek ve aynı resimden oluşur.SideBySide
: Resim veya video karesi, yan yana yerleştirilmiş bir resim ya da video karesi çifti içerir. Soldaki resim veya kare sol göz görünümünü, sağdaki resim veya kare ise sağ göz görünümünü temsil eder.TopBottom
: Resim veya video karesi, dikey olarak yığılmış bir resim veya video karesi çifti içerir. Üstteki resim veya kare sol göz görünümünü, alttaki resim veya kare ise sağ göz görünümünü temsil eder.
SpatialExternalSurface
yalnızca dikdörtgen yüzeyleri destekler.- Bu
Surface
, giriş etkinliklerini yakalamaz. StereoMode
değişiklikleri, uygulama oluşturma veya video kod çözme ile senkronize edilemez.- Bu kompozisyon diğer panellerin önünde oluşturulamaz. Bu nedenle, düzende başka paneller varsa hareketli değiştiricileri kullanmamalısınız.
Diğer mekansal kullanıcı arayüzü bileşenlerini ekleme
Mekansal kullanıcı arayüzü bileşenleri, uygulamanızın kullanıcı arayüzü hiyerarşisinin herhangi bir yerine yerleştirilebilir. Bu öğeler 2D kullanıcı arayüzünüzde yeniden kullanılabilir ve bu öğelerin uzamsal özellikleri yalnızca uzamsal özellikler etkinleştirildiğinde görünür. Bu sayede, kodunuzu iki kez yazmak zorunda kalmadan menülere, iletişim kutularına ve diğer bileşenlere yükseklik ekleyebilirsiniz. Bu öğeleri nasıl kullanacağınızı daha iyi anlamak için aşağıdaki mekansal kullanıcı arayüzü örneklerine göz atın.
Kullanıcı Arayüzü Bileşeni |
Uzamsallaştırma etkinleştirildiğinde |
2D ortamda |
---|---|---|
|
Panel, yükseltilmiş bir iletişim kutusu görüntülemek için z-derinliğinde biraz geriye itilir. |
2D'ye |
|
Panel, yükseltilmiş bir pop-up görüntülemek için z-derinliğinde biraz geriye itilir. |
2D |
|
|
Mekansal yükseklik içermeyen programlar. |
SpatialDialog
Bu, kısa bir gecikme sonrasında açılan bir iletişim kutusu örneğidir. SpatialDialog
kullanıldığında iletişim kutusu, uzamsal panelle aynı z-derinliğinde görünür ve uzamsallaştırma etkinleştirildiğinde panel 125 dp geriye itilir. SpatialDialog
, uzamsallaştırma etkin olmadığında da kullanılabilir. Bu durumda SpatialDialog
, 2D karşılığı olan Dialog
'ye geri döner.
@Composable fun DelayedDialog() { var showDialog by remember { mutableStateOf(false) } LaunchedEffect(Unit) { delay(3000) showDialog = true } if (showDialog) { SpatialDialog( onDismissRequest = { showDialog = false }, SpatialDialogProperties( dismissOnBackPress = true ) ) { Box( Modifier .height(150.dp) .width(150.dp) ) { Button(onClick = { showDialog = false }) { Text("OK") } } } } }
Kodla ilgili önemli noktalar
- Bu,
SpatialDialog
örneğidir.SpatialPopup
veSpatialElevation
kullanmanın işlevi çok benzerdir. Daha fazla bilgi için API referansımıza bakın.
Özel paneller ve düzenler oluşturma
XR için Compose tarafından desteklenmeyen özel paneller oluşturmak istiyorsanız SceneCore
API'lerini kullanarak doğrudan PanelEntities
ve sahne grafiğiyle çalışabilirsiniz.
Yörüngeleri mekansal düzenlere ve diğer öğelere sabitleme
Bir yörünge aracını, Oluştur'da tanımlanan herhangi bir öğeye sabitleyebilirsiniz. Bu, SpatialRow
, SpatialColumn
veya SpatialBox
gibi kullanıcı arayüzü öğelerinin bulunduğu bir uzamsal düzende bir yörünge aracının tanımlanmasını içerir. Yörünge, belirttiğiniz yere en yakın üst öğeye sabitlenir.
Yörünge aracının davranışı, onu nerede beyan ettiğinize göre belirlenir:
SpatialPanel
içine sarmalanmış 2D bir düzende (önceki kod snippet'inde gösterildiği gibi), yörünge aracı buSpatialPanel
'e sabitlenir.Subspace
içinde, yörünge aracı en yakın üst öğeye sabitlenir. Bu öğe, yörünge aracının tanımlandığı uzamsal düzendir.
Aşağıdaki örnekte, bir yörünge aracının bir uzamsal satıra nasıl sabitleneceği gösterilmektedir:
Subspace { SpatialRow { Orbiter( position = OrbiterEdge.Top, offset = EdgeOffset.inner(8.dp), shape = SpatialRoundedCornerShape(size = CornerSize(50)) ) { Text( "Hello World!", style = MaterialTheme.typography.h2, modifier = Modifier .background(Color.White) .padding(16.dp) ) } SpatialPanel( SubspaceModifier .height(824.dp) .width(1400.dp) ) { Box( modifier = Modifier .background(Color.Red) ) } SpatialPanel( SubspaceModifier .height(824.dp) .width(1400.dp) ) { Box( modifier = Modifier .background(Color.Blue) ) } } }
Kodla ilgili önemli noktalar
- 2D düzenin dışında bir yörüngeci tanımladığınızda yörüngeci, en yakın üst öğesine sabitlenir. Bu durumda, yörünge aracı, tanımlandığı
SpatialRow
öğesinin üst kısmına sabitlenir. SpatialRow
,SpatialColumn
,SpatialBox
gibi tüm mekansal düzenlerin kendileriyle ilişkili içeriksiz varlıkları vardır. Bu nedenle, bir uzamsal düzende tanımlanan yörünge aracı, söz konusu düzene sabitlenir.
Ayrıca bkz.
- Uygulamanıza 3D model ekleme
- Android Görünümlere dayalı uygulamalar için kullanıcı arayüzü geliştirme
- XR için Materyal Tasarım'ı uygulama