Android XR SDK এখন ডেভেলপার প্রিভিউতে উপলব্ধ। আমরা আপনার প্রতিক্রিয়া চাই! পৌঁছানোর জন্য আমাদের
সমর্থন পৃষ্ঠা দেখুন।
XR-এর জন্য Jetpack Compose দিয়ে UI ডেভেলপ করুন
সেভ করা পৃষ্ঠা গুছিয়ে রাখতে 'সংগ্রহ' ব্যবহার করুন
আপনার পছন্দ অনুযায়ী কন্টেন্ট সেভ করুন ও সঠিক বিভাগে রাখুন।
XR-এর জন্য Jetpack Compose-এর মাধ্যমে, আপনি সারি এবং কলামের মতো পরিচিত রচনা ধারণা ব্যবহার করে ঘোষণামূলকভাবে আপনার স্থানিক UI এবং বিন্যাস তৈরি করতে পারেন। এটি আপনাকে আপনার বিদ্যমান Android UI 3D স্পেসে প্রসারিত করতে বা সম্পূর্ণ নতুন নিমজ্জিত 3D অ্যাপ্লিকেশন তৈরি করতে দেয়৷
আপনি যদি একটি বিদ্যমান অ্যান্ড্রয়েড ভিউ-ভিত্তিক অ্যাপকে স্থানান্তরিত করেন তবে আপনার কাছে বেশ কয়েকটি বিকাশের বিকল্প রয়েছে। আপনি আন্তঃঅপারেবিলিটি API ব্যবহার করতে পারেন, কম্পোজ এবং ভিউ একসাথে ব্যবহার করতে পারেন, অথবা সিনকোর লাইব্রেরির সাথে সরাসরি কাজ করতে পারেন। আরও বিস্তারিত জানার জন্য ভিউ নিয়ে কাজ করার জন্য আমাদের গাইড দেখুন।

কোডল্যাব
Android XR ফান্ডামেন্টালগুলি জানুন: পার্ট 1 - মোড এবং স্থানিক প্যানেল
arrow_forward সাবস্পেস এবং স্থানিক উপাদান সম্পর্কে
আপনি যখন Android XR-এর জন্য আপনার অ্যাপ লিখছেন, তখন সাবস্পেস এবং স্থানিক উপাদানগুলির ধারণাগুলি বোঝা গুরুত্বপূর্ণ৷
সাবস্পেস সম্পর্কে
Android XR-এর জন্য বিকাশ করার সময়, আপনাকে আপনার অ্যাপ বা লেআউটে একটি সাবস্পেস যোগ করতে হবে। একটি সাবস্পেস হল আপনার অ্যাপের মধ্যে 3D স্পেসের একটি পার্টিশন যেখানে আপনি 3D সামগ্রী রাখতে পারেন, 3D লেআউট তৈরি করতে পারেন এবং অন্যথায় 2D সামগ্রীতে গভীরতা যোগ করতে পারেন। স্থানিককরণ সক্ষম হলেই একটি সাবস্পেস রেন্ডার করা হয়। হোম স্পেস বা নন-এক্সআর ডিভাইসে, সেই সাবস্পেসের মধ্যে যেকোন কোড উপেক্ষা করা হয়।
একটি সাবস্পেস তৈরি করার দুটি উপায় আছে:
-
setSubspaceContent()
: এই ফাংশনটি একটি অ্যাপ-লেভেল সাবস্পেস তৈরি করে। এটিকে আপনার প্রধান কার্যকলাপে বলা যেতে পারে যেভাবে আপনি setContent()
ব্যবহার করেন। একটি অ্যাপ-লেভেল সাবস্পেস উচ্চতা, প্রস্থ এবং গভীরতায় সীমাহীন, মূলত স্থানিক বিষয়বস্তুর জন্য একটি অসীম ক্যানভাস প্রদান করে। -
Subspace
: এই সংমিশ্রণযোগ্যটিকে আপনার অ্যাপের UI অনুক্রমের মধ্যে যে কোনও জায়গায় স্থাপন করা যেতে পারে, যা আপনাকে ফাইলগুলির মধ্যে প্রসঙ্গ না হারিয়ে 2D এবং স্থানিক UI এর জন্য লেআউটগুলি বজায় রাখতে দেয়৷ এটি আপনার পুরো UI ট্রির মাধ্যমে স্টেট উত্তোলনের প্রয়োজন ছাড়াই XR এবং অন্যান্য ফর্ম ফ্যাক্টরগুলির মধ্যে বিদ্যমান অ্যাপ আর্কিটেকচারের মতো জিনিসগুলিকে ভাগ করা সহজ করে তোলে বা আপনার অ্যাপকে পুনরায় আর্কিটেক্ট করার প্রয়োজন নেই৷
আরও তথ্যের জন্য, আপনার অ্যাপে একটি সাবস্পেস যোগ করুন দেখুন।
স্থানিক উপাদান সম্পর্কে
সাবস্পেস কম্পোজেবল : এই উপাদানগুলি শুধুমাত্র একটি সাবস্পেসে রেন্ডার করা যেতে পারে। একটি 2D লেআউটের মধ্যে স্থাপন করার আগে সেগুলি অবশ্যই Subspace
বা setSubspaceContent
মধ্যে আবদ্ধ থাকতে হবে৷ একটি SubspaceModifier
আপনাকে আপনার সাবস্পেস কম্পোজেবলগুলিতে গভীরতা, অফসেট এবং অবস্থানের মতো বৈশিষ্ট্যগুলি যোগ করতে দেয়।
অন্যান্য স্থানিক উপাদানগুলির একটি সাবস্পেসের ভিতরে ডাকা প্রয়োজন হয় না। তারা একটি স্থানিক পাত্রের মধ্যে আবৃত প্রচলিত 2D উপাদান নিয়ে গঠিত। এই উপাদানগুলি 2D বা 3D লেআউটের মধ্যে ব্যবহার করা যেতে পারে যদি উভয়ের জন্য সংজ্ঞায়িত করা হয়। যখন স্থানিকীকরণ সক্ষম না হয়, তখন তাদের স্থানিক বৈশিষ্ট্যগুলি উপেক্ষা করা হবে এবং তারা তাদের 2D প্রতিরূপগুলিতে ফিরে আসবে৷
একটি স্থানিক প্যানেল তৈরি করুন
একটি SpatialPanel
হল একটি সাবস্পেস কম্পোজযোগ্য যা আপনাকে অ্যাপের সামগ্রী প্রদর্শন করতে দেয়-উদাহরণস্বরূপ, আপনি একটি স্থানিক প্যানেলে ভিডিও প্লেব্যাক, স্থির চিত্র বা অন্য কোনো সামগ্রী প্রদর্শন করতে পারেন।

আপনি স্থানিক প্যানেলের আকার, আচরণ এবং অবস্থান পরিবর্তন করতে SubspaceModifier
ব্যবহার করতে পারেন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে।
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
)
}
}
কোড সম্পর্কে মূল পয়েন্ট
কিভাবে একটি চলমান সাবস্পেস সংশোধক কাজ করে
যেহেতু একজন ব্যবহারকারী একটি প্যানেলকে তাদের থেকে দূরে সরিয়ে দেয়, ডিফল্টরূপে একটি চলমান সাবস্পেস মডিফায়ার প্যানেলটিকে একইভাবে স্কেল করে যেভাবে হোম স্পেসে সিস্টেম দ্বারা প্যানেলের আকার পরিবর্তন করা হয়। সমস্ত শিশু বিষয়বস্তু এই আচরণের উত্তরাধিকারী। এটি নিষ্ক্রিয় করতে, scaleWithDistance
প্যারামিটারটিকে false
সেট করুন।
একটি অরবিটার তৈরি করুন
একটি অরবিটার একটি স্থানিক UI উপাদান। এটি একটি সংশ্লিষ্ট স্থানিক প্যানেল, লেআউট বা অন্যান্য সত্তার সাথে সংযুক্ত করার জন্য ডিজাইন করা হয়েছে। একটি অরবিটারে সাধারণত ন্যাভিগেশন এবং প্রাসঙ্গিক অ্যাকশন আইটেম থাকে যা এটি নোঙর করা হয় তার সাথে সম্পর্কিত। উদাহরণস্বরূপ, আপনি যদি ভিডিও সামগ্রী প্রদর্শনের জন্য একটি স্থানিক প্যানেল তৈরি করে থাকেন, তাহলে আপনি একটি অরবিটারের ভিতরে ভিডিও প্লেব্যাক নিয়ন্ত্রণ যোগ করতে পারেন।

নিম্নলিখিত উদাহরণে দেখানো হয়েছে, ন্যাভিগেশনের মতো ব্যবহারকারীর নিয়ন্ত্রণগুলি মোড়ানোর জন্য একটি SpatialPanel
এ 2D লেআউটের ভিতরে একটি অরবিটারকে কল করুন। এটি করা আপনার 2D লেআউট থেকে এগুলিকে বের করে এবং আপনার কনফিগারেশন অনুযায়ী স্থানিক প্যানেলে সংযুক্ত করে।
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
)
}
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
- যেহেতু অরবিটারগুলি স্থানিক UI উপাদান, কোডটি 2D বা 3D লেআউটে পুনরায় ব্যবহার করা যেতে পারে। একটি 2D বিন্যাসে, আপনার অ্যাপ শুধুমাত্র অরবিটারের ভিতরের বিষয়বস্তু রেন্ডার করে এবং অরবিটারকে উপেক্ষা করে।
- অরবিটারগুলি কীভাবে ব্যবহার এবং ডিজাইন করবেন সে সম্পর্কে আরও তথ্যের জন্য আমাদের নকশা নির্দেশিকা দেখুন।
একটি স্থানিক বিন্যাসে একাধিক স্থানিক প্যানেল যোগ করুন
আপনি একাধিক স্থানিক প্যানেল তৈরি করতে পারেন এবং SpatialRow
, SpatialColumn
, SpatialBox
, এবং SpatialLayoutSpacer
ব্যবহার করে একটি স্থানিক বিন্যাসের মধ্যে তাদের স্থাপন করতে পারেন৷

নিম্নলিখিত কোড উদাহরণ দেখায় কিভাবে এটি করতে হয়.
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
ব্যবহার করুন। - একটি সারিতে একাধিক প্যানেল সহ লেআউটের জন্য, আমরা একটি
SubspaceModifier
ব্যবহার করে 825dp এর একটি কার্ভ ব্যাসার্ধ সেট করার পরামর্শ দিই যাতে প্যানেলগুলি আপনার ব্যবহারকারীকে ঘিরে থাকে৷ বিস্তারিত জানার জন্য আমাদের ডিজাইন নির্দেশিকা দেখুন।
আপনার লেআউটে একটি 3D বস্তু স্থাপন করতে একটি ভলিউম ব্যবহার করুন
আপনার লেআউটে একটি 3D অবজেক্ট স্থাপন করতে, আপনাকে একটি সাবস্পেস কম্পোজেবল ব্যবহার করতে হবে যাকে ভলিউম বলা হয়। এটি কিভাবে করতে হয় তার একটি উদাহরণ এখানে।

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) {
অতিরিক্ত তথ্য
ছবি বা ভিডিও সামগ্রীর জন্য একটি পৃষ্ঠ যোগ করুন
একটি SpatialExternalSurface
হল একটি সাবস্পেস কম্পোজেবল যা Surface
তৈরি এবং পরিচালনা করে যেখানে আপনার অ্যাপ ছবি বা ভিডিওর মতো বিষয়বস্তু আঁকতে পারে। SpatialExternalSurface
হয় স্টেরিওস্কোপিক বা মনোস্কোপিক বিষয়বস্তু সমর্থন করে।
এই উদাহরণটি দেখায় কিভাবে মিডিয়া3 এক্সোপ্লেয়ার এবং SpatialExternalSurface
ব্যবহার করে পাশাপাশি স্টেরিওস্কোপিক ভিডিও লোড করতে হয়:
@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() }
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
- আপনি কোন ধরনের সামগ্রী রেন্ডার করছেন তার উপর নির্ভর করে
StereoMode
Mono
, SideBySide
, বা TopBottom
এ সেট করুন:-
Mono
: ইমেজ বা ভিডিও ফ্রেমে একটি একক, অভিন্ন চিত্র থাকে যা উভয় চোখেই দেখানো হয়। -
SideBySide
: ইমেজ বা ভিডিও ফ্রেমে একজোড়া ছবি বা ভিডিও ফ্রেম পাশাপাশি সাজানো থাকে, যেখানে বাম দিকের ছবি বা ফ্রেমটি বাম চোখের দৃশ্যকে উপস্থাপন করে এবং ডানদিকের ছবি বা ফ্রেমটি ডান চোখের দৃশ্যকে উপস্থাপন করে। -
TopBottom
: ইমেজ বা ভিডিও ফ্রেমে উল্লম্বভাবে স্ট্যাক করা এক জোড়া ছবি বা ভিডিও ফ্রেম থাকে, যেখানে উপরের ছবি বা ফ্রেমটি বাম চোখের দৃশ্যকে প্রতিনিধিত্ব করে এবং নীচের ছবিটি বা ফ্রেমটি ডান চোখের দৃশ্যকে উপস্থাপন করে।
-
SpatialExternalSurface
শুধুমাত্র আয়তক্ষেত্রাকার পৃষ্ঠতল সমর্থন করে। - এই
Surface
ইনপুট ইভেন্টগুলি ক্যাপচার করে না। - অ্যাপ্লিকেশন রেন্ডারিং বা ভিডিও ডিকোডিংয়ের সাথে
StereoMode
পরিবর্তনগুলি সিঙ্ক্রোনাইজ করা সম্ভব নয়৷ - এই কম্পোজেবলটি অন্য প্যানেলের সামনে রেন্ডার করতে পারে না, তাই লেআউটে অন্য প্যানেল থাকলে আপনার চলমান পরিবর্তনকারী ব্যবহার করা উচিত নয়।
অন্যান্য স্থানিক UI উপাদান যোগ করুন
স্থানিক UI উপাদানগুলি আপনার অ্যাপ্লিকেশনের UI অনুক্রমের যে কোনও জায়গায় স্থাপন করা যেতে পারে। এই উপাদানগুলি আপনার 2D UI তে পুনরায় ব্যবহার করা যেতে পারে, এবং তাদের স্থানিক বৈশিষ্ট্যগুলি শুধুমাত্র তখনই দৃশ্যমান হবে যখন স্থানিক ক্ষমতাগুলি সক্ষম হবে৷ এটি আপনাকে আপনার কোড দুবার লেখার প্রয়োজন ছাড়াই মেনু, ডায়ালগ এবং অন্যান্য উপাদানগুলিতে উচ্চতা যোগ করতে দেয়। এই উপাদানগুলি কীভাবে ব্যবহার করবেন তা আরও ভালভাবে বুঝতে স্থানিক UI এর নিম্নলিখিত উদাহরণগুলি দেখুন।
UI উপাদান | যখন স্থানিককরণ সক্ষম করা হয় | 2D পরিবেশে |
---|
SpatialDialog | একটি উন্নত ডায়ালগ প্রদর্শন করতে প্যানেলটি z-গভীরতায় কিছুটা পিছনে ঠেলে দেবে | 2D Dialog ফিরে আসে। |
SpatialPopup | প্যানেল একটি উন্নত পপআপ প্রদর্শন করতে z-গভীরতায় কিছুটা পিছনে ঠেলে দেবে | একটি 2D Popup ফিরে আসে। |
SpatialElevation | SpatialElevationLevel উচ্চতা যোগ করতে সেট করা যেতে পারে। | স্থানিক উচ্চতা ছাড়াই দেখায়। |
স্থানিক ডায়ালগ
এটি একটি সংলাপের একটি উদাহরণ যা অল্প বিলম্বের পরে খোলে৷ যখন SpatialDialog
ব্যবহার করা হয়, তখন ডায়ালগটি স্থানিক প্যানেলের মতো একই z-গভীরতায় উপস্থিত হয় এবং যখন স্থানিককরণ সক্ষম করা হয় তখন প্যানেলটি 125dp দ্বারা পিছনে ঠেলে দেওয়া হয়। SpatialDialog
ব্যবহার করা যেতে পারে যখন স্থানিকীকরণ সক্ষম না থাকে, সেক্ষেত্রে SpatialDialog
এর 2D প্রতিরূপ, Dialog
ফিরে আসে।
@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")
}
}
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
কাস্টম প্যানেল এবং লেআউট তৈরি করুন
XR-এর জন্য রচনা দ্বারা সমর্থিত নয় এমন কাস্টম প্যানেল তৈরি করতে, আপনি SceneCore
API ব্যবহার করে সরাসরি PanelEntities
এবং দৃশ্য গ্রাফের সাথে কাজ করতে পারেন।
স্থানিক বিন্যাস এবং অন্যান্য সত্তা নোঙ্গর অরবিটার
আপনি কম্পোজে ঘোষিত যেকোন সত্তায় একটি অরবিটারকে অ্যাঙ্কর করতে পারেন। এর মধ্যে UI উপাদান যেমন SpatialRow
, SpatialColumn
, বা SpatialBox
এর একটি স্থানিক বিন্যাসে একটি অরবিটার ঘোষণা করা জড়িত। আপনি যেখানে এটি ঘোষণা করেছেন তার নিকটবর্তী মূল সত্তায় অরবিটার অ্যাঙ্কর করে।
অরবিটারের আচরণ আপনি যেখানে ঘোষণা করেন তার দ্বারা নির্ধারিত হয়:
- একটি
SpatialPanel
এ মোড়ানো একটি 2D বিন্যাসে ( পূর্ববর্তী কোড স্নিপেটে দেখানো হয়েছে), অরবিটার সেই SpatialPanel
এ নোঙর করে। - একটি
Subspace
, অরবিটারটি নিকটতম মূল সত্তার কাছে নোঙ্গর করে, যা স্থানিক বিন্যাস যেখানে অরবিটার ঘোষণা করা হয়।
নিম্নলিখিত উদাহরণ দেখায় কিভাবে একটি স্থানিক সারিতে একটি অরবিটারকে নোঙ্গর করতে হয়:
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)
)
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
- আপনি যখন একটি 2D লেআউটের বাইরে একটি অরবিটার ঘোষণা করেন, তখন অরবিটারটি তার নিকটতম মূল সত্তায় নোঙর করে। এই ক্ষেত্রে, অরবিটার নোঙ্গর করে
SpatialRow
এর শীর্ষে এটি ঘোষণা করা হয়েছে। - স্থানিক বিন্যাস যেমন
SpatialRow
, SpatialColumn
, SpatialBox
সকলের সাথে বিষয়বস্তুহীন সত্তা যুক্ত থাকে৷ অতএব, একটি স্থানিক বিন্যাসে ঘোষিত একটি অরবিটার সেই বিন্যাসে নোঙর করে।
এছাড়াও দেখুন
, XR-এর জন্য Jetpack Compose-এর মাধ্যমে, আপনি সারি এবং কলামের মতো পরিচিত রচনা ধারণা ব্যবহার করে ঘোষণামূলকভাবে আপনার স্থানিক UI এবং বিন্যাস তৈরি করতে পারেন। এটি আপনাকে আপনার বিদ্যমান Android UI 3D স্পেসে প্রসারিত করতে বা সম্পূর্ণ নতুন নিমজ্জিত 3D অ্যাপ্লিকেশন তৈরি করতে দেয়৷
আপনি যদি একটি বিদ্যমান অ্যান্ড্রয়েড ভিউ-ভিত্তিক অ্যাপকে স্থানান্তরিত করেন তবে আপনার কাছে বেশ কয়েকটি বিকাশের বিকল্প রয়েছে। আপনি আন্তঃঅপারেবিলিটি API ব্যবহার করতে পারেন, কম্পোজ এবং ভিউ একসাথে ব্যবহার করতে পারেন, অথবা সিনকোর লাইব্রেরির সাথে সরাসরি কাজ করতে পারেন। আরও বিস্তারিত জানার জন্য ভিউ নিয়ে কাজ করার জন্য আমাদের গাইড দেখুন।

কোডল্যাব
Android XR ফান্ডামেন্টালগুলি জানুন: পার্ট 1 - মোড এবং স্থানিক প্যানেল
arrow_forward সাবস্পেস এবং স্থানিক উপাদান সম্পর্কে
আপনি যখন Android XR-এর জন্য আপনার অ্যাপ লিখছেন, তখন সাবস্পেস এবং স্থানিক উপাদানগুলির ধারণাগুলি বোঝা গুরুত্বপূর্ণ৷
সাবস্পেস সম্পর্কে
Android XR-এর জন্য বিকাশ করার সময়, আপনাকে আপনার অ্যাপ বা লেআউটে একটি সাবস্পেস যোগ করতে হবে। একটি সাবস্পেস হল আপনার অ্যাপের মধ্যে 3D স্পেসের একটি পার্টিশন যেখানে আপনি 3D সামগ্রী রাখতে পারেন, 3D লেআউট তৈরি করতে পারেন এবং অন্যথায় 2D সামগ্রীতে গভীরতা যোগ করতে পারেন। স্থানিককরণ সক্ষম হলেই একটি সাবস্পেস রেন্ডার করা হয়। হোম স্পেস বা নন-এক্সআর ডিভাইসে, সেই সাবস্পেসের মধ্যে যেকোন কোড উপেক্ষা করা হয়।
একটি সাবস্পেস তৈরি করার দুটি উপায় আছে:
-
setSubspaceContent()
: এই ফাংশনটি একটি অ্যাপ-লেভেল সাবস্পেস তৈরি করে। এটিকে আপনার প্রধান কার্যকলাপে বলা যেতে পারে যেভাবে আপনি setContent()
ব্যবহার করেন। একটি অ্যাপ-লেভেল সাবস্পেস উচ্চতা, প্রস্থ এবং গভীরতায় সীমাহীন, মূলত স্থানিক বিষয়বস্তুর জন্য একটি অসীম ক্যানভাস প্রদান করে। -
Subspace
: এই সংমিশ্রণযোগ্যটিকে আপনার অ্যাপের UI অনুক্রমের মধ্যে যে কোনও জায়গায় স্থাপন করা যেতে পারে, যা আপনাকে ফাইলগুলির মধ্যে প্রসঙ্গ না হারিয়ে 2D এবং স্থানিক UI এর জন্য লেআউটগুলি বজায় রাখতে দেয়৷ এটি আপনার পুরো UI ট্রির মাধ্যমে স্টেট উত্তোলনের প্রয়োজন ছাড়াই XR এবং অন্যান্য ফর্ম ফ্যাক্টরগুলির মধ্যে বিদ্যমান অ্যাপ আর্কিটেকচারের মতো জিনিসগুলিকে ভাগ করা সহজ করে তোলে বা আপনার অ্যাপকে পুনরায় আর্কিটেক্ট করার প্রয়োজন নেই৷
আরও তথ্যের জন্য, আপনার অ্যাপে একটি সাবস্পেস যোগ করুন দেখুন।
স্থানিক উপাদান সম্পর্কে
সাবস্পেস কম্পোজেবল : এই উপাদানগুলি শুধুমাত্র একটি সাবস্পেসে রেন্ডার করা যেতে পারে। একটি 2D লেআউটের মধ্যে স্থাপন করার আগে সেগুলি অবশ্যই Subspace
বা setSubspaceContent
মধ্যে আবদ্ধ থাকতে হবে৷ একটি SubspaceModifier
আপনাকে আপনার সাবস্পেস কম্পোজেবলগুলিতে গভীরতা, অফসেট এবং অবস্থানের মতো বৈশিষ্ট্যগুলি যোগ করতে দেয়।
অন্যান্য স্থানিক উপাদানগুলির একটি সাবস্পেসের ভিতরে ডাকা প্রয়োজন হয় না। তারা একটি স্থানিক পাত্রের মধ্যে আবৃত প্রচলিত 2D উপাদান নিয়ে গঠিত। এই উপাদানগুলি 2D বা 3D লেআউটের মধ্যে ব্যবহার করা যেতে পারে যদি উভয়ের জন্য সংজ্ঞায়িত করা হয়। যখন স্থানিকীকরণ সক্ষম না হয়, তখন তাদের স্থানিক বৈশিষ্ট্যগুলি উপেক্ষা করা হবে এবং তারা তাদের 2D প্রতিরূপগুলিতে ফিরে আসবে৷
একটি স্থানিক প্যানেল তৈরি করুন
একটি SpatialPanel
হল একটি সাবস্পেস কম্পোজযোগ্য যা আপনাকে অ্যাপের সামগ্রী প্রদর্শন করতে দেয়-উদাহরণস্বরূপ, আপনি একটি স্থানিক প্যানেলে ভিডিও প্লেব্যাক, স্থির চিত্র বা অন্য কোনো সামগ্রী প্রদর্শন করতে পারেন।

আপনি স্থানিক প্যানেলের আকার, আচরণ এবং অবস্থান পরিবর্তন করতে SubspaceModifier
ব্যবহার করতে পারেন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে।
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
)
}
}
কোড সম্পর্কে মূল পয়েন্ট
কিভাবে একটি চলমান সাবস্পেস সংশোধক কাজ করে
যেহেতু একজন ব্যবহারকারী একটি প্যানেলকে তাদের থেকে দূরে সরিয়ে দেয়, ডিফল্টরূপে একটি চলমান সাবস্পেস মডিফায়ার প্যানেলটিকে একইভাবে স্কেল করে যেভাবে হোম স্পেসে সিস্টেম দ্বারা প্যানেলের আকার পরিবর্তন করা হয়। সমস্ত শিশু বিষয়বস্তু এই আচরণের উত্তরাধিকারী। এটি নিষ্ক্রিয় করতে, scaleWithDistance
প্যারামিটারটিকে false
সেট করুন।
একটি অরবিটার তৈরি করুন
একটি অরবিটার একটি স্থানিক UI উপাদান। এটি একটি সংশ্লিষ্ট স্থানিক প্যানেল, লেআউট বা অন্যান্য সত্তার সাথে সংযুক্ত করার জন্য ডিজাইন করা হয়েছে। একটি অরবিটারে সাধারণত ন্যাভিগেশন এবং প্রাসঙ্গিক অ্যাকশন আইটেম থাকে যা এটি নোঙর করা হয় তার সাথে সম্পর্কিত। উদাহরণস্বরূপ, আপনি যদি ভিডিও সামগ্রী প্রদর্শনের জন্য একটি স্থানিক প্যানেল তৈরি করে থাকেন, তাহলে আপনি একটি অরবিটারের ভিতরে ভিডিও প্লেব্যাক নিয়ন্ত্রণ যোগ করতে পারেন।

নিম্নলিখিত উদাহরণে দেখানো হয়েছে, ন্যাভিগেশনের মতো ব্যবহারকারীর নিয়ন্ত্রণগুলি মোড়ানোর জন্য একটি SpatialPanel
এ 2D লেআউটের ভিতরে একটি অরবিটারকে কল করুন। এটি করা আপনার 2D লেআউট থেকে এগুলিকে বের করে এবং আপনার কনফিগারেশন অনুযায়ী স্থানিক প্যানেলে সংযুক্ত করে।
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
)
}
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
- যেহেতু অরবিটারগুলি স্থানিক UI উপাদান, কোডটি 2D বা 3D লেআউটে পুনরায় ব্যবহার করা যেতে পারে। একটি 2D বিন্যাসে, আপনার অ্যাপ শুধুমাত্র অরবিটারের ভিতরের বিষয়বস্তু রেন্ডার করে এবং অরবিটারকে উপেক্ষা করে।
- অরবিটারগুলি কীভাবে ব্যবহার এবং ডিজাইন করবেন সে সম্পর্কে আরও তথ্যের জন্য আমাদের নকশা নির্দেশিকা দেখুন।
একটি স্থানিক বিন্যাসে একাধিক স্থানিক প্যানেল যোগ করুন
আপনি একাধিক স্থানিক প্যানেল তৈরি করতে পারেন এবং SpatialRow
, SpatialColumn
, SpatialBox
, এবং SpatialLayoutSpacer
ব্যবহার করে একটি স্থানিক বিন্যাসের মধ্যে তাদের স্থাপন করতে পারেন৷

নিম্নলিখিত কোড উদাহরণ দেখায় কিভাবে এটি করতে হয়.
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
ব্যবহার করুন। - একটি সারিতে একাধিক প্যানেল সহ লেআউটের জন্য, আমরা একটি
SubspaceModifier
ব্যবহার করে 825dp এর একটি কার্ভ ব্যাসার্ধ সেট করার পরামর্শ দিই যাতে প্যানেলগুলি আপনার ব্যবহারকারীকে ঘিরে থাকে৷ বিস্তারিত জানার জন্য আমাদের ডিজাইন নির্দেশিকা দেখুন।
আপনার লেআউটে একটি 3D বস্তু স্থাপন করতে একটি ভলিউম ব্যবহার করুন
আপনার লেআউটে একটি 3D অবজেক্ট স্থাপন করতে, আপনাকে একটি সাবস্পেস কম্পোজেবল ব্যবহার করতে হবে যাকে ভলিউম বলা হয়। এটি কিভাবে করতে হয় তার একটি উদাহরণ এখানে।

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) {
অতিরিক্ত তথ্য
ছবি বা ভিডিও সামগ্রীর জন্য একটি পৃষ্ঠ যোগ করুন
একটি SpatialExternalSurface
হল একটি সাবস্পেস কম্পোজেবল যা Surface
তৈরি এবং পরিচালনা করে যেখানে আপনার অ্যাপ ছবি বা ভিডিওর মতো বিষয়বস্তু আঁকতে পারে। SpatialExternalSurface
হয় স্টেরিওস্কোপিক বা মনোস্কোপিক বিষয়বস্তু সমর্থন করে।
এই উদাহরণটি দেখায় কিভাবে মিডিয়া3 এক্সোপ্লেয়ার এবং SpatialExternalSurface
ব্যবহার করে পাশাপাশি স্টেরিওস্কোপিক ভিডিও লোড করতে হয়:
@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() }
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
- আপনি কোন ধরনের সামগ্রী রেন্ডার করছেন তার উপর নির্ভর করে
StereoMode
Mono
, SideBySide
, বা TopBottom
এ সেট করুন:-
Mono
: ইমেজ বা ভিডিও ফ্রেমে একটি একক, অভিন্ন চিত্র থাকে যা উভয় চোখেই দেখানো হয়। -
SideBySide
: ইমেজ বা ভিডিও ফ্রেমে একজোড়া ছবি বা ভিডিও ফ্রেম পাশাপাশি সাজানো থাকে, যেখানে বাম দিকের ছবি বা ফ্রেমটি বাম চোখের দৃশ্যকে উপস্থাপন করে এবং ডানদিকের ছবি বা ফ্রেমটি ডান চোখের দৃশ্যকে উপস্থাপন করে। -
TopBottom
: ইমেজ বা ভিডিও ফ্রেমে উল্লম্বভাবে স্ট্যাক করা এক জোড়া ছবি বা ভিডিও ফ্রেম থাকে, যেখানে উপরের ছবি বা ফ্রেমটি বাম চোখের দৃশ্যকে প্রতিনিধিত্ব করে এবং নীচের ছবিটি বা ফ্রেমটি ডান চোখের দৃশ্যকে উপস্থাপন করে।
-
SpatialExternalSurface
শুধুমাত্র আয়তক্ষেত্রাকার পৃষ্ঠতল সমর্থন করে। - এই
Surface
ইনপুট ইভেন্টগুলি ক্যাপচার করে না। - অ্যাপ্লিকেশন রেন্ডারিং বা ভিডিও ডিকোডিংয়ের সাথে
StereoMode
পরিবর্তনগুলি সিঙ্ক্রোনাইজ করা সম্ভব নয়৷ - এই কম্পোজেবলটি অন্য প্যানেলের সামনে রেন্ডার করতে পারে না, তাই লেআউটে অন্য প্যানেল থাকলে আপনার চলমান পরিবর্তনকারী ব্যবহার করা উচিত নয়।
অন্যান্য স্থানিক UI উপাদান যোগ করুন
স্থানিক UI উপাদানগুলি আপনার অ্যাপ্লিকেশনের UI অনুক্রমের যে কোনও জায়গায় স্থাপন করা যেতে পারে। এই উপাদানগুলি আপনার 2D UI তে পুনরায় ব্যবহার করা যেতে পারে, এবং তাদের স্থানিক বৈশিষ্ট্যগুলি শুধুমাত্র তখনই দৃশ্যমান হবে যখন স্থানিক ক্ষমতাগুলি সক্ষম হবে৷ এটি আপনাকে আপনার কোড দুবার লেখার প্রয়োজন ছাড়াই মেনু, ডায়ালগ এবং অন্যান্য উপাদানগুলিতে উচ্চতা যোগ করতে দেয়। এই উপাদানগুলি কীভাবে ব্যবহার করবেন তা আরও ভালভাবে বুঝতে স্থানিক UI এর নিম্নলিখিত উদাহরণগুলি দেখুন।
UI উপাদান | যখন স্থানিককরণ সক্ষম করা হয় | 2D পরিবেশে |
---|
SpatialDialog | একটি উন্নত ডায়ালগ প্রদর্শন করতে প্যানেলটি z-গভীরতায় কিছুটা পিছনে ঠেলে দেবে | 2D Dialog ফিরে আসে। |
SpatialPopup | প্যানেল একটি উন্নত পপআপ প্রদর্শন করতে z-গভীরতায় কিছুটা পিছনে ঠেলে দেবে | একটি 2D Popup ফিরে আসে। |
SpatialElevation | SpatialElevationLevel উচ্চতা যোগ করতে সেট করা যেতে পারে। | স্থানিক উচ্চতা ছাড়াই দেখায়। |
স্থানিক ডায়ালগ
এটি একটি সংলাপের একটি উদাহরণ যা অল্প বিলম্বের পরে খোলে৷ যখন SpatialDialog
ব্যবহার করা হয়, তখন ডায়ালগটি স্থানিক প্যানেলের মতো একই z-গভীরতায় উপস্থিত হয় এবং যখন স্থানিককরণ সক্ষম করা হয় তখন প্যানেলটি 125dp দ্বারা পিছনে ঠেলে দেওয়া হয়। SpatialDialog
ব্যবহার করা যেতে পারে যখন স্থানিকীকরণ সক্ষম না থাকে, সেক্ষেত্রে SpatialDialog
এর 2D প্রতিরূপ, Dialog
ফিরে আসে।
@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")
}
}
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
কাস্টম প্যানেল এবং লেআউট তৈরি করুন
XR-এর জন্য রচনা দ্বারা সমর্থিত নয় এমন কাস্টম প্যানেল তৈরি করতে, আপনি SceneCore
API ব্যবহার করে সরাসরি PanelEntities
এবং দৃশ্য গ্রাফের সাথে কাজ করতে পারেন।
স্থানিক বিন্যাস এবং অন্যান্য সত্তা নোঙ্গর অরবিটার
আপনি কম্পোজে ঘোষিত যেকোন সত্তায় একটি অরবিটারকে অ্যাঙ্কর করতে পারেন। এর মধ্যে UI উপাদান যেমন SpatialRow
, SpatialColumn
, বা SpatialBox
এর একটি স্থানিক বিন্যাসে একটি অরবিটার ঘোষণা করা জড়িত। আপনি যেখানে এটি ঘোষণা করেছেন তার নিকটবর্তী মূল সত্তায় অরবিটার অ্যাঙ্কর করে।
অরবিটারের আচরণ আপনি যেখানে ঘোষণা করেন তার দ্বারা নির্ধারিত হয়:
- একটি
SpatialPanel
এ মোড়ানো একটি 2D বিন্যাসে ( পূর্ববর্তী কোড স্নিপেটে দেখানো হয়েছে), অরবিটার সেই SpatialPanel
এ নোঙর করে। - একটি
Subspace
, অরবিটারটি নিকটতম মূল সত্তার কাছে নোঙ্গর করে, যা স্থানিক বিন্যাস যেখানে অরবিটার ঘোষণা করা হয়।
নিম্নলিখিত উদাহরণ দেখায় কিভাবে একটি স্থানিক সারিতে একটি অরবিটারকে নোঙ্গর করতে হয়:
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)
)
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
- আপনি যখন একটি 2D লেআউটের বাইরে একটি অরবিটার ঘোষণা করেন, তখন অরবিটারটি তার নিকটতম মূল সত্তায় নোঙর করে। এই ক্ষেত্রে, অরবিটার নোঙ্গর করে
SpatialRow
এর শীর্ষে এটি ঘোষণা করা হয়েছে। - স্থানিক বিন্যাস যেমন
SpatialRow
, SpatialColumn
, SpatialBox
সকলের সাথে বিষয়বস্তুহীন সত্তা যুক্ত থাকে৷ অতএব, একটি স্থানিক বিন্যাসে ঘোষিত একটি অরবিটার সেই বিন্যাসে নোঙর করে।
এছাড়াও দেখুন
, XR-এর জন্য Jetpack Compose-এর মাধ্যমে, আপনি সারি এবং কলামের মতো পরিচিত রচনা ধারণা ব্যবহার করে ঘোষণামূলকভাবে আপনার স্থানিক UI এবং বিন্যাস তৈরি করতে পারেন। এটি আপনাকে আপনার বিদ্যমান Android UI 3D স্পেসে প্রসারিত করতে বা সম্পূর্ণ নতুন নিমজ্জিত 3D অ্যাপ্লিকেশন তৈরি করতে দেয়৷
আপনি যদি একটি বিদ্যমান অ্যান্ড্রয়েড ভিউ-ভিত্তিক অ্যাপকে স্থানান্তরিত করেন তবে আপনার কাছে বেশ কয়েকটি বিকাশের বিকল্প রয়েছে। আপনি আন্তঃঅপারেবিলিটি API ব্যবহার করতে পারেন, কম্পোজ এবং ভিউ একসাথে ব্যবহার করতে পারেন, অথবা সিনকোর লাইব্রেরির সাথে সরাসরি কাজ করতে পারেন। আরও বিস্তারিত জানার জন্য ভিউ নিয়ে কাজ করার জন্য আমাদের গাইড দেখুন।

কোডল্যাব
Android XR ফান্ডামেন্টালগুলি জানুন: পার্ট 1 - মোড এবং স্থানিক প্যানেল
arrow_forward সাবস্পেস এবং স্থানিক উপাদান সম্পর্কে
আপনি যখন Android XR-এর জন্য আপনার অ্যাপ লিখছেন, তখন সাবস্পেস এবং স্থানিক উপাদানগুলির ধারণাগুলি বোঝা গুরুত্বপূর্ণ৷
সাবস্পেস সম্পর্কে
Android XR-এর জন্য বিকাশ করার সময়, আপনাকে আপনার অ্যাপ বা লেআউটে একটি সাবস্পেস যোগ করতে হবে। একটি সাবস্পেস হল আপনার অ্যাপের মধ্যে 3D স্পেসের একটি পার্টিশন যেখানে আপনি 3D সামগ্রী রাখতে পারেন, 3D লেআউট তৈরি করতে পারেন এবং অন্যথায় 2D সামগ্রীতে গভীরতা যোগ করতে পারেন। স্থানিককরণ সক্ষম হলেই একটি সাবস্পেস রেন্ডার করা হয়। হোম স্পেস বা নন-এক্সআর ডিভাইসে, সেই সাবস্পেসের মধ্যে যেকোন কোড উপেক্ষা করা হয়।
একটি সাবস্পেস তৈরি করার দুটি উপায় আছে:
-
setSubspaceContent()
: এই ফাংশনটি একটি অ্যাপ-লেভেল সাবস্পেস তৈরি করে। এটিকে আপনার প্রধান কার্যকলাপে বলা যেতে পারে যেভাবে আপনি setContent()
ব্যবহার করেন। একটি অ্যাপ-লেভেল সাবস্পেস উচ্চতা, প্রস্থ এবং গভীরতায় সীমাহীন, মূলত স্থানিক বিষয়বস্তুর জন্য একটি অসীম ক্যানভাস প্রদান করে। -
Subspace
: এই সংমিশ্রণযোগ্যটিকে আপনার অ্যাপের UI অনুক্রমের মধ্যে যে কোনও জায়গায় স্থাপন করা যেতে পারে, যা আপনাকে ফাইলগুলির মধ্যে প্রসঙ্গ না হারিয়ে 2D এবং স্থানিক UI এর জন্য লেআউটগুলি বজায় রাখতে দেয়৷ এটি আপনার পুরো UI ট্রির মাধ্যমে স্টেট উত্তোলনের প্রয়োজন ছাড়াই XR এবং অন্যান্য ফর্ম ফ্যাক্টরগুলির মধ্যে বিদ্যমান অ্যাপ আর্কিটেকচারের মতো জিনিসগুলিকে ভাগ করা সহজ করে তোলে বা আপনার অ্যাপকে পুনরায় আর্কিটেক্ট করার প্রয়োজন নেই৷
আরও তথ্যের জন্য, আপনার অ্যাপে একটি সাবস্পেস যোগ করুন দেখুন।
স্থানিক উপাদান সম্পর্কে
সাবস্পেস কম্পোজেবল : এই উপাদানগুলি শুধুমাত্র একটি সাবস্পেসে রেন্ডার করা যেতে পারে। একটি 2D লেআউটের মধ্যে স্থাপন করার আগে সেগুলি অবশ্যই Subspace
বা setSubspaceContent
মধ্যে আবদ্ধ থাকতে হবে৷ একটি SubspaceModifier
আপনাকে আপনার সাবস্পেস কম্পোজেবলগুলিতে গভীরতা, অফসেট এবং অবস্থানের মতো বৈশিষ্ট্যগুলি যোগ করতে দেয়।
অন্যান্য স্থানিক উপাদানগুলির একটি সাবস্পেসের ভিতরে ডাকা প্রয়োজন হয় না। তারা একটি স্থানিক পাত্রের মধ্যে আবৃত প্রচলিত 2D উপাদান নিয়ে গঠিত। এই উপাদানগুলি 2D বা 3D লেআউটের মধ্যে ব্যবহার করা যেতে পারে যদি উভয়ের জন্য সংজ্ঞায়িত করা হয়। যখন স্থানিকীকরণ সক্ষম না হয়, তখন তাদের স্থানিক বৈশিষ্ট্যগুলি উপেক্ষা করা হবে এবং তারা তাদের 2D প্রতিরূপগুলিতে ফিরে আসবে৷
একটি স্থানিক প্যানেল তৈরি করুন
একটি SpatialPanel
হল একটি সাবস্পেস কম্পোজযোগ্য যা আপনাকে অ্যাপের সামগ্রী প্রদর্শন করতে দেয়-উদাহরণস্বরূপ, আপনি একটি স্থানিক প্যানেলে ভিডিও প্লেব্যাক, স্থির চিত্র বা অন্য কোনো সামগ্রী প্রদর্শন করতে পারেন।

আপনি স্থানিক প্যানেলের আকার, আচরণ এবং অবস্থান পরিবর্তন করতে SubspaceModifier
ব্যবহার করতে পারেন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে।
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
)
}
}
কোড সম্পর্কে মূল পয়েন্ট
কিভাবে একটি চলমান সাবস্পেস সংশোধক কাজ করে
যেহেতু একজন ব্যবহারকারী একটি প্যানেলকে তাদের থেকে দূরে সরিয়ে দেয়, ডিফল্টরূপে একটি চলমান সাবস্পেস মডিফায়ার প্যানেলটিকে একইভাবে স্কেল করে যেভাবে হোম স্পেসে সিস্টেম দ্বারা প্যানেলের আকার পরিবর্তন করা হয়। সমস্ত শিশু বিষয়বস্তু এই আচরণের উত্তরাধিকারী। এটি নিষ্ক্রিয় করতে, scaleWithDistance
প্যারামিটারটিকে false
সেট করুন।
একটি অরবিটার তৈরি করুন
একটি অরবিটার একটি স্থানিক UI উপাদান। এটি একটি সংশ্লিষ্ট স্থানিক প্যানেল, লেআউট বা অন্যান্য সত্তার সাথে সংযুক্ত করার জন্য ডিজাইন করা হয়েছে। একটি অরবিটারে সাধারণত ন্যাভিগেশন এবং প্রাসঙ্গিক অ্যাকশন আইটেম থাকে যা এটি নোঙর করা হয় তার সাথে সম্পর্কিত। উদাহরণস্বরূপ, আপনি যদি ভিডিও সামগ্রী প্রদর্শনের জন্য একটি স্থানিক প্যানেল তৈরি করে থাকেন, তাহলে আপনি একটি অরবিটারের ভিতরে ভিডিও প্লেব্যাক নিয়ন্ত্রণ যোগ করতে পারেন।

নিম্নলিখিত উদাহরণে দেখানো হয়েছে, ন্যাভিগেশনের মতো ব্যবহারকারীর নিয়ন্ত্রণগুলি মোড়ানোর জন্য একটি SpatialPanel
এ 2D লেআউটের ভিতরে একটি অরবিটারকে কল করুন। এটি করা আপনার 2D লেআউট থেকে এগুলিকে বের করে এবং আপনার কনফিগারেশন অনুযায়ী স্থানিক প্যানেলে সংযুক্ত করে।
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
)
}
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
- যেহেতু অরবিটারগুলি স্থানিক UI উপাদান, কোডটি 2D বা 3D লেআউটে পুনরায় ব্যবহার করা যেতে পারে। একটি 2D বিন্যাসে, আপনার অ্যাপ শুধুমাত্র অরবিটারের ভিতরের বিষয়বস্তু রেন্ডার করে এবং অরবিটারকে উপেক্ষা করে।
- অরবিটারগুলি কীভাবে ব্যবহার এবং ডিজাইন করবেন সে সম্পর্কে আরও তথ্যের জন্য আমাদের নকশা নির্দেশিকা দেখুন।
একটি স্থানিক বিন্যাসে একাধিক স্থানিক প্যানেল যোগ করুন
আপনি একাধিক স্থানিক প্যানেল তৈরি করতে পারেন এবং SpatialRow
, SpatialColumn
, SpatialBox
, এবং SpatialLayoutSpacer
ব্যবহার করে একটি স্থানিক বিন্যাসের মধ্যে তাদের স্থাপন করতে পারেন৷

নিম্নলিখিত কোড উদাহরণ দেখায় কিভাবে এটি করতে হয়.
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
ব্যবহার করুন। - একটি সারিতে একাধিক প্যানেল সহ লেআউটের জন্য, আমরা একটি
SubspaceModifier
ব্যবহার করে 825dp এর একটি কার্ভ ব্যাসার্ধ সেট করার পরামর্শ দিই যাতে প্যানেলগুলি আপনার ব্যবহারকারীকে ঘিরে থাকে৷ বিস্তারিত জানার জন্য আমাদের ডিজাইন নির্দেশিকা দেখুন।
আপনার লেআউটে একটি 3D বস্তু স্থাপন করতে একটি ভলিউম ব্যবহার করুন
আপনার লেআউটে একটি 3D অবজেক্ট স্থাপন করতে, আপনাকে একটি সাবস্পেস কম্পোজেবল ব্যবহার করতে হবে যাকে ভলিউম বলা হয়। এটি কিভাবে করতে হয় তার একটি উদাহরণ এখানে।

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) {
অতিরিক্ত তথ্য
ছবি বা ভিডিও সামগ্রীর জন্য একটি পৃষ্ঠ যোগ করুন
একটি SpatialExternalSurface
হল একটি সাবস্পেস কম্পোজেবল যা Surface
তৈরি এবং পরিচালনা করে যেখানে আপনার অ্যাপ ছবি বা ভিডিওর মতো বিষয়বস্তু আঁকতে পারে। SpatialExternalSurface
হয় স্টেরিওস্কোপিক বা মনোস্কোপিক বিষয়বস্তু সমর্থন করে।
এই উদাহরণটি দেখায় কিভাবে মিডিয়া3 এক্সোপ্লেয়ার এবং SpatialExternalSurface
ব্যবহার করে পাশাপাশি স্টেরিওস্কোপিক ভিডিও লোড করতে হয়:
@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() }
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
- আপনি কোন ধরনের সামগ্রী রেন্ডার করছেন তার উপর নির্ভর করে
StereoMode
Mono
, SideBySide
, বা TopBottom
এ সেট করুন:-
Mono
: ইমেজ বা ভিডিও ফ্রেমে একটি একক, অভিন্ন চিত্র থাকে যা উভয় চোখেই দেখানো হয়। -
SideBySide
: ইমেজ বা ভিডিও ফ্রেমে একজোড়া ছবি বা ভিডিও ফ্রেম পাশাপাশি সাজানো থাকে, যেখানে বাম দিকের ছবি বা ফ্রেমটি বাম চোখের দৃশ্যকে উপস্থাপন করে এবং ডানদিকের ছবি বা ফ্রেমটি ডান চোখের দৃশ্যকে উপস্থাপন করে। -
TopBottom
: ইমেজ বা ভিডিও ফ্রেমে উল্লম্বভাবে স্ট্যাক করা এক জোড়া ছবি বা ভিডিও ফ্রেম থাকে, যেখানে উপরের ছবি বা ফ্রেমটি বাম চোখের দৃশ্যকে প্রতিনিধিত্ব করে এবং নীচের ছবিটি বা ফ্রেমটি ডান চোখের দৃশ্যকে উপস্থাপন করে।
-
SpatialExternalSurface
শুধুমাত্র আয়তক্ষেত্রাকার পৃষ্ঠতল সমর্থন করে। - এই
Surface
ইনপুট ইভেন্টগুলি ক্যাপচার করে না। - অ্যাপ্লিকেশন রেন্ডারিং বা ভিডিও ডিকোডিংয়ের সাথে
StereoMode
পরিবর্তনগুলি সিঙ্ক্রোনাইজ করা সম্ভব নয়৷ - এই কম্পোজেবলটি অন্য প্যানেলের সামনে রেন্ডার করতে পারে না, তাই লেআউটে অন্য প্যানেল থাকলে আপনার চলমান পরিবর্তনকারী ব্যবহার করা উচিত নয়।
অন্যান্য স্থানিক UI উপাদান যোগ করুন
স্থানিক UI উপাদানগুলি আপনার অ্যাপ্লিকেশনের UI অনুক্রমের যে কোনও জায়গায় স্থাপন করা যেতে পারে। এই উপাদানগুলি আপনার 2D UI তে পুনরায় ব্যবহার করা যেতে পারে, এবং তাদের স্থানিক বৈশিষ্ট্যগুলি শুধুমাত্র তখনই দৃশ্যমান হবে যখন স্থানিক ক্ষমতাগুলি সক্ষম হবে৷ এটি আপনাকে আপনার কোড দুবার লেখার প্রয়োজন ছাড়াই মেনু, ডায়ালগ এবং অন্যান্য উপাদানগুলিতে উচ্চতা যোগ করতে দেয়। এই উপাদানগুলি কীভাবে ব্যবহার করবেন তা আরও ভালভাবে বুঝতে স্থানিক UI এর নিম্নলিখিত উদাহরণগুলি দেখুন।
UI উপাদান | যখন স্থানিককরণ সক্ষম করা হয় | 2D পরিবেশে |
---|
SpatialDialog | একটি উন্নত ডায়ালগ প্রদর্শন করতে প্যানেলটি z-গভীরতায় কিছুটা পিছনে ঠেলে দেবে | 2D Dialog ফিরে আসে। |
SpatialPopup | প্যানেল একটি উন্নত পপআপ প্রদর্শন করতে z-গভীরতায় কিছুটা পিছনে ঠেলে দেবে | একটি 2D Popup ফিরে আসে। |
SpatialElevation | SpatialElevationLevel উচ্চতা যোগ করতে সেট করা যেতে পারে। | স্থানিক উচ্চতা ছাড়াই দেখায়। |
স্থানিক ডায়ালগ
এটি একটি সংলাপের একটি উদাহরণ যা অল্প বিলম্বের পরে খোলে৷ যখন SpatialDialog
ব্যবহার করা হয়, তখন ডায়ালগটি স্থানিক প্যানেলের মতো একই z-গভীরতায় উপস্থিত হয় এবং যখন স্থানিককরণ সক্ষম করা হয় তখন প্যানেলটি 125dp দ্বারা পিছনে ঠেলে দেওয়া হয়। SpatialDialog
ব্যবহার করা যেতে পারে যখন স্থানিকীকরণ সক্ষম না থাকে, সেক্ষেত্রে SpatialDialog
এর 2D প্রতিরূপ, Dialog
ফিরে আসে।
@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")
}
}
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
কাস্টম প্যানেল এবং লেআউট তৈরি করুন
XR-এর জন্য রচনা দ্বারা সমর্থিত নয় এমন কাস্টম প্যানেল তৈরি করতে, আপনি SceneCore
API ব্যবহার করে সরাসরি PanelEntities
এবং দৃশ্য গ্রাফের সাথে কাজ করতে পারেন।
স্থানিক বিন্যাস এবং অন্যান্য সত্তা নোঙ্গর অরবিটার
আপনি কম্পোজে ঘোষিত যেকোন সত্তায় একটি অরবিটারকে অ্যাঙ্কর করতে পারেন। এর মধ্যে UI উপাদান যেমন SpatialRow
, SpatialColumn
, বা SpatialBox
এর একটি স্থানিক বিন্যাসে একটি অরবিটার ঘোষণা করা জড়িত। আপনি যেখানে এটি ঘোষণা করেছেন তার নিকটবর্তী মূল সত্তায় অরবিটার অ্যাঙ্কর করে।
অরবিটারের আচরণ আপনি যেখানে ঘোষণা করেন তার দ্বারা নির্ধারিত হয়:
- একটি
SpatialPanel
এ মোড়ানো একটি 2D বিন্যাসে ( পূর্ববর্তী কোড স্নিপেটে দেখানো হয়েছে), অরবিটার সেই SpatialPanel
এ নোঙর করে। - একটি
Subspace
, অরবিটারটি নিকটতম মূল সত্তার কাছে নোঙ্গর করে, যা স্থানিক বিন্যাস যেখানে অরবিটার ঘোষণা করা হয়।
নিম্নলিখিত উদাহরণ দেখায় কিভাবে একটি স্থানিক সারিতে একটি অরবিটারকে নোঙ্গর করতে হয়:
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)
)
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
- আপনি যখন একটি 2D লেআউটের বাইরে একটি অরবিটার ঘোষণা করেন, তখন অরবিটারটি তার নিকটতম মূল সত্তায় নোঙর করে। এই ক্ষেত্রে, অরবিটার নোঙ্গর করে
SpatialRow
এর শীর্ষে এটি ঘোষণা করা হয়েছে। - স্থানিক বিন্যাস যেমন
SpatialRow
, SpatialColumn
, SpatialBox
সকলের সাথে বিষয়বস্তুহীন সত্তা যুক্ত থাকে৷ অতএব, একটি স্থানিক বিন্যাসে ঘোষিত একটি অরবিটার সেই বিন্যাসে নোঙর করে।
এছাড়াও দেখুন
, XR-এর জন্য Jetpack Compose-এর মাধ্যমে, আপনি সারি এবং কলামের মতো পরিচিত রচনা ধারণা ব্যবহার করে ঘোষণামূলকভাবে আপনার স্থানিক UI এবং বিন্যাস তৈরি করতে পারেন। এটি আপনাকে আপনার বিদ্যমান Android UI 3D স্পেসে প্রসারিত করতে বা সম্পূর্ণ নতুন নিমজ্জিত 3D অ্যাপ্লিকেশন তৈরি করতে দেয়৷
আপনি যদি একটি বিদ্যমান অ্যান্ড্রয়েড ভিউ-ভিত্তিক অ্যাপকে স্থানান্তরিত করেন তবে আপনার কাছে বেশ কয়েকটি বিকাশের বিকল্প রয়েছে। আপনি আন্তঃঅপারেবিলিটি API ব্যবহার করতে পারেন, কম্পোজ এবং ভিউ একসাথে ব্যবহার করতে পারেন, অথবা সিনকোর লাইব্রেরির সাথে সরাসরি কাজ করতে পারেন। আরও বিস্তারিত জানার জন্য ভিউ নিয়ে কাজ করার জন্য আমাদের গাইড দেখুন।

কোডল্যাব
Android XR ফান্ডামেন্টালগুলি জানুন: পার্ট 1 - মোড এবং স্থানিক প্যানেল
arrow_forward সাবস্পেস এবং স্থানিক উপাদান সম্পর্কে
আপনি যখন Android XR-এর জন্য আপনার অ্যাপ লিখছেন, তখন সাবস্পেস এবং স্থানিক উপাদানগুলির ধারণাগুলি বোঝা গুরুত্বপূর্ণ৷
সাবস্পেস সম্পর্কে
Android XR-এর জন্য বিকাশ করার সময়, আপনাকে আপনার অ্যাপ বা লেআউটে একটি সাবস্পেস যোগ করতে হবে। একটি সাবস্পেস হল আপনার অ্যাপের মধ্যে 3D স্পেসের একটি পার্টিশন যেখানে আপনি 3D সামগ্রী রাখতে পারেন, 3D লেআউট তৈরি করতে পারেন এবং অন্যথায় 2D সামগ্রীতে গভীরতা যোগ করতে পারেন। স্থানিককরণ সক্ষম হলেই একটি সাবস্পেস রেন্ডার করা হয়। হোম স্পেস বা নন-এক্সআর ডিভাইসে, সেই সাবস্পেসের মধ্যে যেকোন কোড উপেক্ষা করা হয়।
একটি সাবস্পেস তৈরি করার দুটি উপায় আছে:
-
setSubspaceContent()
: এই ফাংশনটি একটি অ্যাপ-লেভেল সাবস্পেস তৈরি করে। এটিকে আপনার প্রধান কার্যকলাপে বলা যেতে পারে যেভাবে আপনি setContent()
ব্যবহার করেন। একটি অ্যাপ-লেভেল সাবস্পেস উচ্চতা, প্রস্থ এবং গভীরতায় সীমাহীন, মূলত স্থানিক বিষয়বস্তুর জন্য একটি অসীম ক্যানভাস প্রদান করে। -
Subspace
: এই সংমিশ্রণযোগ্যটিকে আপনার অ্যাপের UI অনুক্রমের মধ্যে যে কোনও জায়গায় স্থাপন করা যেতে পারে, যা আপনাকে ফাইলগুলির মধ্যে প্রসঙ্গ না হারিয়ে 2D এবং স্থানিক UI এর জন্য লেআউটগুলি বজায় রাখতে দেয়৷ এটি আপনার পুরো UI ট্রির মাধ্যমে স্টেট উত্তোলনের প্রয়োজন ছাড়াই XR এবং অন্যান্য ফর্ম ফ্যাক্টরগুলির মধ্যে বিদ্যমান অ্যাপ আর্কিটেকচারের মতো জিনিসগুলিকে ভাগ করা সহজ করে তোলে বা আপনার অ্যাপকে পুনরায় আর্কিটেক্ট করার প্রয়োজন নেই৷
আরও তথ্যের জন্য, আপনার অ্যাপে একটি সাবস্পেস যোগ করুন দেখুন।
স্থানিক উপাদান সম্পর্কে
সাবস্পেস কম্পোজেবল : এই উপাদানগুলি শুধুমাত্র একটি সাবস্পেসে রেন্ডার করা যেতে পারে। এগুলি অবশ্যই 2 ডি লেআউটের মধ্যে রাখার আগে Subspace
বা setSubspaceContent
মধ্যে আবদ্ধ থাকতে হবে। একটি SubspaceModifier
আপনাকে আপনার সাবস্পেস কমপোজেবলগুলিতে গভীরতা, অফসেট এবং অবস্থানের মতো বৈশিষ্ট্য যুক্ত করতে দেয়।
অন্যান্য স্থানিক উপাদানগুলির জন্য কোনও উপ -স্পেসের ভিতরে কল করা প্রয়োজন হয় না। এগুলিতে একটি স্থানিক পাত্রে মোড়ানো প্রচলিত 2 ডি উপাদান রয়েছে। এই উপাদানগুলি 2 ডি বা 3 ডি লেআউটগুলির মধ্যে ব্যবহার করা যেতে পারে যদি উভয়ের জন্য সংজ্ঞায়িত করা হয়। যখন স্থানিককরণ সক্ষম না করা হয়, তখন তাদের স্থানিক বৈশিষ্ট্যগুলি উপেক্ষা করা হবে এবং তারা তাদের 2 ডি অংশগুলিতে ফিরে আসবে।
একটি স্থানিক প্যানেল তৈরি করুন
একটি SpatialPanel
একটি সাবস্পেস কমপোজেবল যা আপনাকে অ্যাপ্লিকেশন সামগ্রী প্রদর্শন করতে দেয় example উদাহরণস্বরূপ, আপনি ভিডিও প্লেব্যাক, স্থির চিত্রগুলি বা স্থানিক প্যানেলে অন্য কোনও সামগ্রী প্রদর্শন করতে পারেন।

নিম্নলিখিত উদাহরণে দেখানো হয়েছে, স্থানিক প্যানেলের আকার, আচরণ এবং অবস্থান পরিবর্তন করতে আপনি SubspaceModifier
ব্যবহার করতে পারেন।
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
)
}
}
কোড সম্পর্কে মূল পয়েন্ট
একটি অস্থাবর সাবস্পেস মডিফায়ার কীভাবে কাজ করে
যেহেতু কোনও ব্যবহারকারী তাদের থেকে দূরে একটি প্যানেল সরিয়ে নিয়েছে, ডিফল্টরূপে একটি অস্থাবর সাবস্পেস মডিফায়ার প্যানেলটিকে কীভাবে হোম স্পেসে সিস্টেমের দ্বারা পুনরায় আকার দেওয়া হয় তার অনুরূপভাবে প্যানেলটি স্কেল করে। সমস্ত শিশু বিষয়বস্তু এই আচরণের উত্তরাধিকারী। এটি অক্ষম করতে, scaleWithDistance
প্যারামিটারটি false
হিসাবে সেট করুন।
একটি কক্ষপথ তৈরি করুন
একটি কক্ষপথ একটি স্থানিক ইউআই উপাদান। এটি সংশ্লিষ্ট স্থানিক প্যানেল, লেআউট বা অন্যান্য সত্তার সাথে সংযুক্ত হওয়ার জন্য ডিজাইন করা হয়েছে। একটি কক্ষপথের মধ্যে সাধারণত নেভিগেশন এবং প্রাসঙ্গিক ক্রিয়া আইটেম থাকে যার সাথে এটি নোঙ্গর করা সত্তার সাথে সম্পর্কিত। উদাহরণস্বরূপ, আপনি যদি ভিডিও সামগ্রী প্রদর্শনের জন্য একটি স্থানিক প্যানেল তৈরি করে থাকেন তবে আপনি কোনও কক্ষপথের ভিতরে ভিডিও প্লেব্যাক নিয়ন্ত্রণ যুক্ত করতে পারেন।

নিম্নলিখিত উদাহরণে দেখানো হয়েছে, নেভিগেশনের মতো ব্যবহারকারী নিয়ন্ত্রণগুলি মোড়ানোর জন্য একটি SpatialPanel
2 ডি লেআউটের ভিতরে একটি কক্ষপথকে কল করুন। এটি করা আপনার 2 ডি লেআউট থেকে এগুলি বের করে এবং আপনার কনফিগারেশন অনুযায়ী স্থানিক প্যানেলে সংযুক্ত করে।
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
)
}
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
- যেহেতু অরবিটারগুলি স্থানিক ইউআই উপাদান, কোডটি 2 ডি বা 3 ডি লেআউটগুলিতে পুনরায় ব্যবহার করা যেতে পারে। একটি 2 ডি লেআউটে, আপনার অ্যাপ্লিকেশনটি কেবল কক্ষপথের অভ্যন্তরের সামগ্রীটি সরবরাহ করে এবং কক্ষপথটি নিজেই উপেক্ষা করে।
- কীভাবে অরবিটারগুলি ব্যবহার এবং ডিজাইন করবেন সে সম্পর্কে আরও তথ্যের জন্য আমাদের ডিজাইনের নির্দেশিকা দেখুন।
একটি স্থানিক বিন্যাসে একাধিক স্থানিক প্যানেল যুক্ত করুন
আপনি একাধিক স্থানিক প্যানেল তৈরি করতে পারেন এবং এগুলি স্থানিক লেআউটের মধ্যে স্থানিক লেআউটের মধ্যে রাখতে পারেন, SpatialRow
SpatialColumn
, SpatialBox
এবং SpatialLayoutSpacer
ব্যবহার করে।

নিম্নলিখিত কোড উদাহরণটি কীভাবে এটি করতে হয় তা দেখায়।
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
ব্যবহার করুন। - একটানা একাধিক প্যানেলযুক্ত লেআউটগুলির জন্য, আমরা
SubspaceModifier
ব্যবহার করে 825DP এর একটি বক্ররেখা ব্যাসার্ধ সেট করার পরামর্শ দিই যাতে প্যানেলগুলি আপনার ব্যবহারকারীকে ঘিরে রাখবে। বিশদ জন্য আমাদের নকশা নির্দেশিকা দেখুন।
আপনার লেআউটে একটি 3 ডি অবজেক্ট স্থাপন করতে একটি ভলিউম ব্যবহার করুন
আপনার বিন্যাসে একটি 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) {
অতিরিক্ত তথ্য
চিত্র বা ভিডিও সামগ্রীর জন্য একটি পৃষ্ঠ যুক্ত করুন
একটি SpatialExternalSurface
একটি সাবস্পেস কমপোজেবল যা আপনার অ্যাপ্লিকেশনটি যেমন কোনও চিত্র বা ভিডিওর মতো সামগ্রী আঁকতে পারে এমন Surface
তৈরি করে এবং পরিচালনা করে। SpatialExternalSurface
স্টেরিওস্কোপিক বা মনোস্কোপিক সামগ্রীকে সমর্থন করে।
এই উদাহরণটি মিডিয়া 3 এক্সোপ্লেয়ার এবং SpatialExternalSurface
ব্যবহার করে কীভাবে পাশাপাশি স্টেরিওস্কোপিক ভিডিওটি লোড করবেন তা প্রমাণ করে:
@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() }
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
- আপনি কোন ধরণের সামগ্রীর রেন্ডার করছেন তার উপর নির্ভর করে
Mono
, SideBySide
বা TopBottom
StereoMode
সেট করুন:-
Mono
: চিত্র বা ভিডিও ফ্রেমে উভয় চোখকে দেখানো একটি একক, অভিন্ন চিত্র রয়েছে। -
SideBySide
: চিত্র বা ভিডিও ফ্রেমে পাশের পাশাপাশি সাজানো একজোড়া চিত্র বা ভিডিও ফ্রেম রয়েছে, যেখানে বাম দিকের চিত্র বা ফ্রেমটি বাম চোখের দৃশ্যের প্রতিনিধিত্ব করে এবং ডানদিকে চিত্র বা ফ্রেমটি ডান চোখের দৃশ্যের প্রতিনিধিত্ব করে। -
TopBottom
: চিত্র বা ভিডিও ফ্রেমে উল্লম্বভাবে স্ট্যাক করা একজোড়া চিত্র বা ভিডিও ফ্রেম রয়েছে, যেখানে উপরের চিত্র বা ফ্রেমটি বাম চোখের দৃশ্যের প্রতিনিধিত্ব করে এবং নীচের অংশে চিত্র বা ফ্রেমটি ডান চোখের দৃশ্যের প্রতিনিধিত্ব করে।
-
SpatialExternalSurface
কেবল আয়তক্ষেত্রাকার পৃষ্ঠগুলিকে সমর্থন করে। - এই
Surface
ইনপুট ইভেন্টগুলি ক্যাপচার করে না। - অ্যাপ্লিকেশন রেন্ডারিং বা ভিডিও ডিকোডিংয়ের সাথে
StereoMode
পরিবর্তনগুলি সিঙ্ক্রোনাইজ করা সম্ভব নয়। - এই কম্পোজেবল অন্যান্য প্যানেলের সামনে রেন্ডার করতে পারে না, তাই বিন্যাসে অন্য প্যানেল থাকলে আপনার অস্থাবর মডিফায়ার ব্যবহার করা উচিত নয়।
অন্যান্য স্থানিক ইউআই উপাদান যুক্ত করুন
স্থানিক ইউআই উপাদানগুলি আপনার অ্যাপ্লিকেশনটির ইউআই শ্রেণিবিন্যাসের যে কোনও জায়গায় স্থাপন করা যেতে পারে। এই উপাদানগুলি আপনার 2 ডি ইউআইতে পুনরায় ব্যবহার করা যেতে পারে এবং স্থানিক ক্ষমতাগুলি সক্ষম করা হলে তাদের স্থানিক বৈশিষ্ট্যগুলি কেবল তখনই দৃশ্যমান হবে। এটি আপনাকে আপনার কোডটি দু'বার লেখার প্রয়োজন ছাড়াই মেনু, সংলাপ এবং অন্যান্য উপাদানগুলিতে উচ্চতা যুক্ত করতে দেয়। এই উপাদানগুলি কীভাবে ব্যবহার করবেন তা আরও ভালভাবে বুঝতে স্থানিক ইউআইয়ের নিম্নলিখিত উদাহরণগুলি দেখুন।
UI উপাদান | যখন স্থানিকরণ সক্ষম করা হয় | 2 ডি পরিবেশে |
---|
SpatialDialog | একটি এলিভেটেড ডায়ালগ প্রদর্শন করতে প্যানেল জেড-গভীরতায় কিছুটা পিছনে চাপ দেবে | 2 ডি Dialog ফিরে আসে। |
SpatialPopup | একটি এলিভেটেড পপআপ প্রদর্শন করতে প্যানেল জেড-গভীরতায় কিছুটা পিছনে চাপ দেবে | 2 ডি Popup ফিরে পড়ে। |
SpatialElevation | SpatialElevationLevel উচ্চতা যুক্ত করতে সেট করা যেতে পারে। | স্থানিক উচ্চতা ছাড়াই দেখায়। |
স্প্যাটিয়াল্ডিয়ালগ
এটি একটি সংলাপের উদাহরণ যা একটি সংক্ষিপ্ত বিলম্বের পরে খোলে। যখন SpatialDialog
ব্যবহার করা হয়, তখন সংলাপটি স্থানিক প্যানেলের মতো একই জেড-গভীরতায় উপস্থিত হয় এবং স্থানিককরণ সক্ষম করা হলে প্যানেলটি 125DP দ্বারা পিছনে ঠেলে দেওয়া হয়। SpatialDialog
যখন স্থানিককরণ সক্ষম না করা হয় তখনও ব্যবহার করা যেতে পারে, সেক্ষেত্রে SpatialDialog
তার 2 ডি কাউন্টার পার্ট, Dialog
ফিরে আসে।
@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")
}
}
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
কাস্টম প্যানেল এবং বিন্যাস তৈরি করুন
এক্সআর এর জন্য রচনা দ্বারা সমর্থিত নয় এমন কাস্টম প্যানেল তৈরি করতে, আপনি SceneCore
এপিআই ব্যবহার করে সরাসরি PanelEntities
এবং দৃশ্যের গ্রাফের সাথে কাজ করতে পারেন।
স্থানিক লেআউট এবং অন্যান্য সত্তাগুলিতে অ্যাঙ্কর অরবিটার
আপনি কমপোজে ঘোষিত যে কোনও সত্তার কাছে কোনও কক্ষপথকে নোঙ্গর করতে পারেন। এর মধ্যে ইউআই উপাদানগুলির স্থানিক লেআউট যেমন SpatialRow
, SpatialColumn
বা SpatialBox
একটি স্থানিক বিন্যাসে একটি কক্ষপথ ঘোষণা করা জড়িত। আপনি যেখানে ঘোষণা করেছেন তার নিকটতম পিতামাতার সত্তার কাছে অরবিটার নোঙ্গর করে।
কক্ষপথের আচরণটি আপনি কোথায় ঘোষণা করেন তা দ্বারা নির্ধারিত হয়:
- একটি
SpatialPanel
মোড়ানো একটি 2 ডি লেআউটে ( পূর্ববর্তী কোড স্নিপেটে দেখানো হয়েছে), সেই SpatialPanel
কক্ষপথ অ্যাঙ্কর করে। - একটি
Subspace
, নিকটস্থ পিতামাতার সত্তার কক্ষপথ নোঙ্গর, যা স্থানিক বিন্যাস যা কক্ষপথকে ঘোষণা করা হয়।
নিম্নলিখিত উদাহরণটি দেখায় যে কীভাবে কোনও স্থানিক সারিতে কোনও কক্ষপথকে নোঙ্গর করা যায়:
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)
)
}
}
}
কোড সম্পর্কে মূল পয়েন্ট
- আপনি যখন 2 ডি লেআউটের বাইরে কোনও কক্ষপথ ঘোষণা করেন, তখন অরবিটারটি তার নিকটতম পিতামাতার সত্তায় নোঙ্গর করে। এই ক্ষেত্রে, কক্ষপথটি এটি ঘোষণা করা
SpatialRow
শীর্ষে নোঙ্গর করে। - স্থানিক লেআউট যেমন
SpatialRow
, SpatialColumn
, SpatialBox
সাথে তাদের সাথে যুক্ত সামগ্রীহীন সত্তা রয়েছে। অতএব, একটি কক্ষপথ সেই লেআউটে একটি স্থানিক বিন্যাসে নোঙ্গর ঘোষণা করে।
এছাড়াও দেখুন