با Jetpack Compose برای XR، میتوانید رابط کاربری و طرحبندی فضایی خود را با استفاده از مفاهیم آشنای Compose مانند ردیفها و ستونها، به صورت اعلانی بسازید. این به شما امکان میدهد رابط کاربری اندروید موجود خود را به فضای سهبعدی گسترش دهید یا برنامههای سهبعدی فراگیر کاملاً جدیدی بسازید.
اگر در حال فضاسازی یک برنامه مبتنی بر Views اندروید موجود هستید، گزینههای توسعه متعددی دارید. میتوانید از APIهای قابلیت همکاری استفاده کنید، Compose و Views را با هم استفاده کنید، یا مستقیماً با کتابخانه SceneCore کار کنید. برای جزئیات بیشتر به راهنمای ما در مورد کار با Views مراجعه کنید.
کدلب
آموزش اصول اولیه اندروید XR: بخش 1 - حالتها و پنلهای فضایی
arrow_forward
درباره زیرفضاها و اجزای فضاییشده
وقتی دارید برنامهتان را برای اندروید XR مینویسید، درک مفاهیم زیرفضا (subspace) و اجزای فضاییشده (spatialized components) مهم است.
درباره زیرفضا
هنگام توسعه برای اندروید XR، باید یک Subspace به برنامه یا طرحبندی خود اضافه کنید. Subspace یک پارتیشن از فضای سهبعدی درون برنامه شماست که میتوانید محتوای سهبعدی را در آن قرار دهید، طرحبندیهای سهبعدی بسازید و به محتوای دوبعدی عمق اضافه کنید. Subspace فقط زمانی رندر میشود که قابلیت فضاییسازی فعال باشد. در Home Space یا در دستگاههای غیر XR، هر کدی که درون آن Subspace باشد نادیده گرفته میشود.
دو روش برای ایجاد زیرفضا وجود دارد:
Subspace : این ترکیبپذیر را میتوان در هر جایی از سلسله مراتب رابط کاربری برنامه شما قرار داد و به شما امکان میدهد طرحبندیهای رابط کاربری دوبعدی و فضایی را بدون از دست دادن زمینه بین فایلها حفظ کنید. این امر اشتراکگذاری چیزهایی مانند معماری برنامه موجود بین XR و سایر عوامل فرم را بدون نیاز به انتقال وضعیت در کل درخت رابط کاربری یا معماری مجدد برنامه، آسانتر میکند.
کامپوننتهای Subspace : این کامپوننتها فقط میتوانند در یک Subspace رندر شوند. آنها باید قبل از قرار گرفتن در یک طرحبندی دوبعدی، درون Subspace محصور شوند. SubspaceModifier به شما امکان میدهد ویژگیهایی مانند عمق، افست و موقعیتیابی را به کامپوننتهای Subspace خود اضافه کنید.
سایر اجزای فضایی نیازی به فراخوانی درون یک زیرفضا ندارند. آنها از عناصر دوبعدی مرسوم تشکیل شدهاند که درون یک ظرف فضایی قرار گرفتهاند. این عناصر میتوانند در طرحبندیهای دوبعدی یا سهبعدی استفاده شوند، اگر برای هر دو تعریف شده باشند. وقتی فضاییسازی فعال نباشد، ویژگیهای فضایی آنها نادیده گرفته میشوند و به معادلهای دوبعدی خود برمیگردند.
یک پنل فضایی ایجاد کنید
SpatialPanel یک زیرفضای قابل ترکیب است که به شما امکان نمایش محتوای برنامه را میدهد - برای مثال، میتوانید پخش ویدیو، تصاویر ثابت یا هر محتوای دیگری را در یک پنل فضایی نمایش دهید.
شما میتوانید SubspaceModifier برای تغییر اندازه، رفتار و موقعیتیابی پنل spatial استفاده کنید، همانطور که در مثال زیر نشان داده شده است.
از آنجا که APIهای SpatialPanel قابل ترکیب با subspace هستند، باید آنها را داخل Subspace فراخوانی کنید. فراخوانی آنها خارج از subspace باعث ایجاد خطا میشود.
اندازه SpatialPanel با استفاده از مشخصات height و width در SubspaceModifier تنظیم شده است. حذف این مشخصات باعث میشود اندازه پنل با اندازهگیری محتویات آن تعیین شود.
با اضافه کردن MovePolicy به کاربر اجازه دهید یک پنل را جابجا کند.
با اضافه کردن ResizePolicy به کاربر اجازه دهید اندازه یک پنل را تغییر دهد.
وقتی کاربر یک پنل را از خود دور میکند، به طور پیشفرض، MovePolicy پنل را به روشی مشابه تغییر اندازه پنلها توسط سیستم در فضای خانه ، مقیاسبندی میکند. همه محتوای فرزند این رفتار را به ارث میبرند. برای غیرفعال کردن این، پارامتر shouldScaleWithDistance را روی false تنظیم کنید.
یک مدارگرد ایجاد کنید
یک مدارگرد یک کامپوننت رابط کاربری فضایی است. این کامپوننت به گونهای طراحی شده است که به یک پنل فضایی، طرحبندی یا موجودیت دیگر مربوطه متصل شود. یک مدارگرد معمولاً شامل آیتمهای ناوبری و اقدامات زمینهای مرتبط با موجودیتی است که به آن متصل شده است. به عنوان مثال، اگر یک پنل فضایی برای نمایش محتوای ویدیویی ایجاد کردهاید، میتوانید کنترلهای پخش ویدیو را درون یک مدارگرد اضافه کنید.
همانطور که در مثال زیر نشان داده شده است، یک مدارگرد را درون طرح دوبعدی در SpatialPanel فراخوانی کنید تا کنترلهای کاربر مانند ناوبری را در بر بگیرد. انجام این کار آنها را از طرح دوبعدی شما استخراج کرده و مطابق پیکربندی شما به پنل فضایی متصل میکند.
از آنجا که مدارگردها اجزای رابط کاربری فضایی هستند، کد را میتوان در طرحبندیهای دوبعدی یا سهبعدی دوباره استفاده کرد. در یک طرحبندی دوبعدی، برنامه شما فقط محتوای داخل مدارگرد را رندر میکند و خود مدارگرد را نادیده میگیرد.
برای اطلاعات بیشتر در مورد نحوه استفاده و طراحی مدارگردها، راهنمای طراحی ما را بررسی کنید.
برای طرحبندیهایی با چندین پنل در یک ردیف، توصیه میکنیم با استفاده از SubspaceModifier ، شعاع منحنی را روی ۸۲۵dp تنظیم کنید تا پنلها کاربر شما را احاطه کنند. برای جزئیات بیشتر به راهنمای طراحی ما مراجعه کنید.
از SceneCoreEntity برای قرار دادن موجودیتها در طرحبندی خود استفاده کنید
برای قرار دادن یک شیء سهبعدی در طرحبندی خود، باید از یک زیرفضای ترکیبی به نام SceneCoreEntity استفاده کنید. در اینجا مثالی از نحوه انجام این کار آورده شده است.
Subspace{SceneCoreEntity(modifier=SubspaceModifier.offset(x=50.dp),factory={SurfaceEntity.create(session=session,pose=Pose.Identity,stereoMode=SurfaceEntity.StereoMode.MONO)},update={entity->
// compose state changes may be applied to the// SceneCore entity here.entity.stereoMode=SurfaceEntity.StereoMode.SIDE_BY_SIDE},sizeAdapter=SceneCoreEntitySizeAdapter({IntSize2d(it.width,it.height)}),){// Content here will be children of the SceneCoreEntity// in the scene graph.}}
SpatialExternalSurface یک زیرفضای قابل ترکیب است که Surface ایجاد و مدیریت میکند که برنامه شما میتواند محتوا، مانند تصویر یا ویدیو ، را در آن ترسیم کند. SpatialExternalSurface از محتوای استریوسکوپیک یا مونوسکوپیک پشتیبانی میکند.
@OptIn(ExperimentalComposeApi::class)@ComposablefunSpatialExternalSurfaceContent(){valcontext=LocalContext.currentSubspace{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 contentstereoMode=StereoMode.SideBySide,){valexoPlayer=remember{ExoPlayer.Builder(context).build()}valvideoUri=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()valmediaItem=MediaItem.fromUri(videoUri)// onSurfaceCreated is invoked only one time, when the Surface is createdonSurfaceCreated{surface->
exoPlayer.setVideoSurface(surface)exoPlayer.setMediaItem(mediaItem)exoPlayer.prepare()exoPlayer.play()}// onSurfaceDestroyed is invoked when the SpatialExternalSurface composable and its// associated Surface are destroyedonSurfaceDestroyed{exoPlayer.release()}}}}
بسته به نوع محتوایی که رندر میکنید، StereoMode روی Mono ، SideBySide یا TopBottom تنظیم کنید:
Mono : تصویر یا فریم ویدیویی شامل یک تصویر واحد و یکسان است که به هر دو چشم نشان داده میشود.
SideBySide : تصویر یا فریم ویدیویی شامل یک جفت تصویر یا فریم ویدیویی است که در کنار هم قرار گرفتهاند، به طوری که تصویر یا فریم سمت چپ نمایانگر نمای چشم چپ و تصویر یا فریم سمت راست نمایانگر نمای چشم راست است.
TopBottom : تصویر یا فریم ویدیویی شامل یک جفت تصویر یا فریم ویدیویی است که به صورت عمودی روی هم قرار گرفتهاند، که تصویر یا فریم بالا نشان دهنده نمای چشم چپ و تصویر یا فریم پایین نشان دهنده نمای چشم راست است.
همگامسازی تغییرات StereoMode با رندر برنامه یا رمزگشایی ویدیو امکانپذیر نیست.
این ترکیبپذیر نمیتواند جلوی پنلهای دیگر رندر شود، بنابراین اگر پنلهای دیگری در طرحبندی وجود دارد، نباید از MovePolicy استفاده کنید.
یک سطح برای محتوای ویدیویی محافظتشده با DRM اضافه کنید
SpatialExternalSurface همچنین از پخش جریانهای ویدیویی محافظتشده با DRM پشتیبانی میکند. برای فعال کردن این قابلیت، باید یک سطح امن ایجاد کنید که در بافرهای گرافیکی محافظتشده رندر شود. این امر مانع از ضبط محتوا روی صفحه یا دسترسی اجزای سیستم غیرایمن به آن میشود.
برای ایجاد یک سطح امن، پارامتر surfaceProtection را روی SurfaceProtection.Protected در SpatialExternalSurface composable تنظیم کنید. علاوه بر این، باید Media3 Exoplayer را با اطلاعات DRM مناسب پیکربندی کنید تا بتواند دریافت مجوز از یک سرور مجوز را مدیریت کند.
مثال زیر نحوه پیکربندی SpatialExternalSurface و ExoPlayer را برای پخش یک جریان ویدیویی محافظتشده با DRM نشان میدهد:
@OptIn(ExperimentalComposeApi::class)@ComposablefunDrmSpatialVideoPlayer(){valcontext=LocalContext.currentSubspace{SpatialExternalSurface(modifier=SubspaceModifier.width(1200.dp).height(676.dp),stereoMode=StereoMode.SideBySide,surfaceProtection=SurfaceProtection.Protected){valexoPlayer=remember{ExoPlayer.Builder(context).build()}// Define the URI for your DRM-protected content and license server.valvideoUri="https://your-content-provider.com/video.mpd"valdrmLicenseUrl="https://your-license-server.com/license"// Build a MediaItem with the necessary DRM configuration.valmediaItem=MediaItem.Builder().setUri(videoUri).setDrmConfiguration(MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID).setLicenseUri(drmLicenseUrl).build()).build()onSurfaceCreated{surface->
// The created surface is secure and can be used by the player.exoPlayer.setVideoSurface(surface)exoPlayer.setMediaItem(mediaItem)exoPlayer.prepare()exoPlayer.play()}onSurfaceDestroyed{exoPlayer.release()}}}}
سطح محافظتشده: تنظیم surfaceProtection = SurfaceProtection.Protected روی SpatialExternalSurface ضروری است تا Surface زیرین توسط بافرهای امن مناسب برای محتوای DRM پشتیبانی شود.
پیکربندی DRM: شما باید MediaItem با طرح DRM (برای مثال، C.WIDEVINE_UUID ) و URI سرور لایسنس خود پیکربندی کنید. ExoPlayer از این اطلاعات برای مدیریت جلسه DRM استفاده میکند.
محتوای امن: هنگام رندر کردن روی یک سطح محافظتشده، محتوای ویدیو رمزگشایی شده و در یک مسیر امن نمایش داده میشود که به برآورده شدن الزامات مجوز محتوا کمک میکند. این امر همچنین از نمایش محتوا در تصاویر گرفته شده از صفحه نمایش جلوگیری میکند.
افزودن سایر اجزای رابط کاربری فضایی
اجزای رابط کاربری فضایی را میتوان در هر جایی از سلسله مراتب رابط کاربری برنامه شما قرار داد. این عناصر را میتوان در رابط کاربری دوبعدی شما مجدداً استفاده کرد و ویژگیهای مکانی آنها فقط زمانی قابل مشاهده خواهد بود که قابلیتهای مکانی فعال باشند. این به شما امکان میدهد بدون نیاز به نوشتن مجدد کد، به منوها، دیالوگها و سایر اجزا، ارتفاع اضافه کنید. برای درک بهتر نحوه استفاده از این عناصر، به مثالهای زیر از رابط کاربری فضایی مراجعه کنید.
کامپوننت رابط کاربری
وقتی فضاسازی فعال میشود
در محیط دوبعدی
SpatialDialog
پنل کمی در عمق z به عقب فشار داده میشود تا یک کادر محاورهای با ارتفاع بالا نمایش داده شود.
میتوان SpatialElevationLevel برای افزودن ارتفاع تنظیم کرد.
بدون ارتفاع مکانی نشان میدهد.
گفتگوی فضایی
این نمونهای از یک کادر محاورهای است که پس از یک تأخیر کوتاه باز میشود. وقتی از SpatialDialog استفاده میشود، کادر محاورهای در همان عمق z پنل spatial ظاهر میشود و وقتی spatialization فعال باشد، پنل به اندازه ۱۲۵dp به عقب رانده میشود. SpatialDialog همچنین میتواند زمانی که spatialization فعال نیست استفاده شود، که در این صورت SpatialDialog به معادل دوبعدی خود، Dialog ، برمیگردد.
برای ایجاد پنلهای سفارشی که توسط Compose for XR پشتیبانی نمیشوند، میتوانید مستقیماً با نمونههای PanelEntity و نمودار صحنه با استفاده از رابطهای برنامهنویسی SceneCore کار کنید.
اتصال مدارگردها به طرحهای فضایی و سایر نهادها
شما میتوانید یک مدارگرد را به هر موجودیتی که در Compose تعریف شده است، متصل کنید. این شامل تعریف یک مدارگرد در یک طرحبندی فضایی از عناصر رابط کاربری مانند SpatialRow ، SpatialColumn یا SpatialBox میشود. مدارگرد به نزدیکترین موجودیت والد به جایی که آن را تعریف کردهاید، متصل میشود.
رفتار مدارگرد با توجه به جایی که آن را اعلام میکنید تعیین میشود:
در یک طرح دوبعدی که در یک SpatialPanel پیچیده شده است (همانطور که در قطعه کد قبلی نشان داده شده است)، مدارگرد به آن SpatialPanel متصل میشود.
در یک Subspace )، مدارگرد به نزدیکترین موجودیت والد متصل میشود، که همان طرح فضایی است که مدارگرد در آن تعریف شده است.
مثال زیر نحوه اتصال یک مدارگرد به یک ردیف فضایی را نشان میدهد:
وقتی یک مدارگرد را خارج از یک طرح دوبعدی تعریف میکنید، مدارگرد به نزدیکترین موجودیت والد خود متصل میشود. در این حالت، مدارگرد به بالای SpatialRow که در آن تعریف شده است، متصل میشود.
طرحبندیهای فضایی مانند SpatialRow ، SpatialColumn ، SpatialBox همگی دارای موجودیتهای بدون محتوا هستند. بنابراین، یک مدارگرد که در یک طرحبندی فضایی اعلام شده است، به آن طرحبندی متصل میشود.
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2025-12-08 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2025-12-08 بهوقت ساعت هماهنگ جهانی."],[],[]]