XR-এর জন্য Jetpack Compose দিয়ে UI ডেভেলপ করুন

XR-এর জন্য Jetpack Compose-এর মাধ্যমে, আপনি সারি এবং কলামের মতো পরিচিত রচনা ধারণা ব্যবহার করে ঘোষণামূলকভাবে আপনার স্থানিক UI এবং বিন্যাস তৈরি করতে পারেন। এটি আপনাকে আপনার বিদ্যমান Android UI 3D স্পেসে প্রসারিত করতে বা সম্পূর্ণ নতুন নিমজ্জিত 3D অ্যাপ্লিকেশন তৈরি করতে দেয়৷

আপনি যদি একটি বিদ্যমান অ্যান্ড্রয়েড ভিউ-ভিত্তিক অ্যাপকে স্থানান্তরিত করেন তবে আপনার কাছে বেশ কয়েকটি বিকাশের বিকল্প রয়েছে। আপনি আন্তঃঅপারেবিলিটি API ব্যবহার করতে পারেন, কম্পোজ এবং ভিউ একসাথে ব্যবহার করতে পারেন, অথবা সিনকোর লাইব্রেরির সাথে সরাসরি কাজ করতে পারেন। আরও বিস্তারিত জানার জন্য ভিউ নিয়ে কাজ করার জন্য আমাদের গাইড দেখুন।

সাবস্পেস এবং স্থানিক উপাদান সম্পর্কে

আপনি যখন Android XR-এর জন্য আপনার অ্যাপ লিখছেন, তখন সাবস্পেস এবং স্থানিক উপাদানগুলির ধারণাগুলি বোঝা গুরুত্বপূর্ণ৷

সাবস্পেস সম্পর্কে

Android XR-এর জন্য বিকাশ করার সময়, আপনাকে আপনার অ্যাপ বা লেআউটে একটি সাবস্পেস যোগ করতে হবে। একটি সাবস্পেস হল আপনার অ্যাপের মধ্যে 3D স্পেসের একটি পার্টিশন যেখানে আপনি 3D সামগ্রী রাখতে পারেন, 3D লেআউট তৈরি করতে পারেন এবং অন্যথায় 2D সামগ্রীতে গভীরতা যোগ করতে পারেন। স্থানিককরণ সক্ষম হলেই একটি সাবস্পেস রেন্ডার করা হয়। হোম স্পেস বা নন-এক্সআর ডিভাইসে, সেই সাবস্পেসের মধ্যে যেকোন কোড উপেক্ষা করা হয়।

একটি সাবস্পেস তৈরি করার দুটি উপায় আছে:

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

আরও তথ্যের জন্য, আপনার অ্যাপে একটি সাবস্পেস যোগ করার বিষয়ে পড়ুন।

স্থানিক উপাদান সম্পর্কে

সাবস্পেস কম্পোজেবল : এই উপাদানগুলি শুধুমাত্র একটি সাবস্পেসে রেন্ডার করা যেতে পারে। একটি 2D লেআউটের মধ্যে স্থাপন করার আগে সেগুলি অবশ্যই Subspace বা setSubspaceContent মধ্যে আবদ্ধ থাকতে হবে৷ একটি SubspaceModifier আপনাকে আপনার সাবস্পেস কম্পোজেবলগুলিতে গভীরতা, অফসেট এবং অবস্থানের মতো বৈশিষ্ট্যগুলি যোগ করতে দেয়।

  • সাবস্পেস মডিফায়ার সম্পর্কে দ্রষ্টব্য : SubspaceModifier এপিআই-এর অর্ডারের প্রতি গভীর মনোযোগ দিন।
    • একটি মডিফায়ার চেইনে প্রথমে অফসেট ঘটতে হবে
    • চলমান এবং পরিবর্তনযোগ্য শেষ হওয়া আবশ্যক
    • ঘূর্ণন স্কেল আগে প্রয়োগ করা আবশ্যক

অন্যান্য স্থানিক উপাদানগুলির একটি সাবস্পেসের ভিতরে ডাকা প্রয়োজন হয় না। তারা একটি স্থানিক পাত্রের মধ্যে আবৃত প্রচলিত 2D উপাদান নিয়ে গঠিত। এই উপাদানগুলি 2D বা 3D লেআউটের মধ্যে ব্যবহার করা যেতে পারে যদি উভয়ের জন্য সংজ্ঞায়িত করা হয়। যখন স্থানিকীকরণ সক্ষম না হয়, তখন তাদের স্থানিক বৈশিষ্ট্যগুলি উপেক্ষা করা হবে এবং তারা তাদের 2D প্রতিরূপগুলিতে ফিরে আসবে৷

একটি স্থানিক প্যানেল তৈরি করুন

একটি 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
        )
    }
}

কোড সম্পর্কে মূল পয়েন্ট

  • সাবস্পেস মডিফায়ার সম্পর্কে দ্রষ্টব্য : SubspaceModifier এপিআই-এর অর্ডারের প্রতি গভীর মনোযোগ দিন।
    • অফসেটটি প্রথমে একটি মডিফায়ার চেইনে ঘটতে হবে।
    • চলমান এবং পরিবর্তনযোগ্য সংশোধক অবশ্যই শেষ হতে হবে।
    • স্কেল আগে ঘূর্ণন প্রয়োগ করা আবশ্যক.
  • যেহেতু SpatialPanel APIগুলি হল সাবস্পেস কম্পোজেবল, আপনাকে অবশ্যই সেগুলিকে Subspace বা setSubspaceContent ভিতরে কল করতে হবে। তাদের একটি সাবস্পেসের বাইরে কল করলে একটি ব্যতিক্রম হবে।
  • ব্যবহারকারীকে .movable বা .resizable SubspaceModifier s যোগ করে প্যানেলের আকার পরিবর্তন বা সরানোর অনুমতি দিন।
  • আকার এবং অবস্থান সম্পর্কে বিশদ বিবরণের জন্য আমাদের স্থানিক প্যানেল ডিজাইন নির্দেশিকা দেখুন। কোড বাস্তবায়নের উপর আরো সুনির্দিষ্ট তথ্যের জন্য আমাদের রেফারেন্স ডকুমেন্টেশন দেখুন।

একটি অরবিটার তৈরি করুন

একটি অরবিটার একটি স্থানিক UI উপাদান। এটি একটি সংশ্লিষ্ট স্থানিক প্যানেলের সাথে সংযুক্ত করার জন্য ডিজাইন করা হয়েছে এবং এতে সেই স্থানিক প্যানেলের সাথে সম্পর্কিত নেভিগেশন এবং প্রাসঙ্গিক অ্যাকশন আইটেম রয়েছে৷ উদাহরণস্বরূপ, আপনি যদি ভিডিও সামগ্রী প্রদর্শনের জন্য একটি স্থানিক প্যানেল তৈরি করে থাকেন, তাহলে আপনি একটি অরবিটারের ভিতরে ভিডিও প্লেব্যাক নিয়ন্ত্রণ যোগ করতে পারেন।

একটি অরবিটারের উদাহরণ

নিম্নলিখিত উদাহরণে দেখানো হয়েছে, ন্যাভিগেশনের মতো ব্যবহারকারীর নিয়ন্ত্রণগুলি মোড়ানোর জন্য একটি SpatialPanel ভিতরে একটি অরবিটারকে কল করুন। এটি করা আপনার 2D লেআউট থেকে এগুলিকে বের করে এবং আপনার কনফিগারেশন অনুযায়ী স্থানিক প্যানেলে সংযুক্ত করে।

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
                )
            }
        }
    }
}

কোড সম্পর্কে মূল পয়েন্ট

  • সাবস্পেস মডিফায়ার সম্পর্কে দ্রষ্টব্য : SubspaceModifier এপিআইগুলির ক্রমটির প্রতি গভীর মনোযোগ দিন।
    • একটি মডিফায়ার চেইনে প্রথমে অফসেট ঘটতে হবে
    • চলমান এবং পরিবর্তনযোগ্য শেষ হওয়া আবশ্যক
    • ঘূর্ণন স্কেল আগে প্রয়োগ করা আবশ্যক
  • যেহেতু অরবিটারগুলি স্থানিক UI উপাদান, কোডটি 2D বা 3D লেআউটে পুনরায় ব্যবহার করা যেতে পারে। একটি 2D বিন্যাসে, আপনার অ্যাপ শুধুমাত্র অরবিটারের ভিতরের বিষয়বস্তু রেন্ডার করে এবং অরবিটারকে উপেক্ষা করে।
  • অরবিটারগুলি কীভাবে ব্যবহার এবং ডিজাইন করবেন সে সম্পর্কে আরও তথ্যের জন্য আমাদের নকশা নির্দেশিকা দেখুন।

একটি স্থানিক বিন্যাসে একাধিক স্থানিক প্যানেল যোগ করুন

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

আপনার লেআউটে একটি 3D বস্তু স্থাপন করতে একটি ভলিউম ব্যবহার করুন

আপনার লেআউটে একটি 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) {
    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
                }
            }
        }
    }
}

কোড সম্পর্কে মূল পয়েন্ট

  • সাবস্পেস মডিফায়ার সম্পর্কে দ্রষ্টব্য : SubspaceModifier এপিআইগুলির ক্রমটির প্রতি গভীর মনোযোগ দিন।
    • একটি মডিফায়ার চেইনে প্রথমে অফসেট ঘটতে হবে
    • চলমান এবং পরিবর্তনযোগ্য শেষ হওয়া আবশ্যক
    • ঘূর্ণন স্কেল আগে প্রয়োগ করা আবশ্যক
  • ভলিউমের মধ্যে কীভাবে 3D সামগ্রী লোড করতে হয় তা আরও ভালভাবে বুঝতে 3D সামগ্রী যুক্ত করা দেখুন৷

অন্যান্য স্থানিক UI উপাদান যোগ করুন

স্থানিক UI উপাদানগুলি আপনার অ্যাপ্লিকেশনের UI অনুক্রমের যে কোনও জায়গায় স্থাপন করা যেতে পারে। এই উপাদানগুলি আপনার 2D UI তে পুনরায় ব্যবহার করা যেতে পারে, এবং তাদের স্থানিক বৈশিষ্ট্যগুলি শুধুমাত্র তখনই দৃশ্যমান হবে যখন স্থানিক ক্ষমতাগুলি সক্ষম হবে৷ এটি আপনাকে আপনার কোড দুবার লেখার প্রয়োজন ছাড়াই মেনু, ডায়ালগ এবং অন্যান্য উপাদানগুলিতে উচ্চতা যোগ করতে দেয়। এই উপাদানগুলি কীভাবে ব্যবহার করবেন তা আরও ভালভাবে বুঝতে স্থানিক UI এর নিম্নলিখিত উদাহরণগুলি দেখুন।

UI উপাদান

যখন স্থানিককরণ সক্ষম করা হয়

2D পরিবেশে

SpatialDialog

একটি উন্নত ডায়ালগ প্রদর্শন করতে প্যানেলটি z-গভীরতায় কিছুটা পিছনে ঠেলে দেবে

2D Dialog ফিরে আসে।

SpatialPopUp

প্যানেল একটি উন্নত পপআপ প্রদর্শন করতে z-গভীরতায় কিছুটা পিছনে ঠেলে দেবে

একটি 2D PopUp ফিরে আসে।

SpatialElevation

SpatialElevationLevel উচ্চতা যোগ করতে সেট করা যেতে পারে।

স্থানিক উচ্চতা ছাড়াই দেখায়।

স্থানিক ডায়ালগ

এটি একটি সংলাপের একটি উদাহরণ যা অল্প বিলম্বের পরে খোলে৷ যখন SpatialDialog ব্যবহার করা হয়, তখন ডায়ালগটি স্থানিক প্যানেলের মতো একই z-গভীরতায় উপস্থিত হয় এবং যখন স্থানিককরণ সক্ষম করা হয় তখন প্যানেলটি 125dp দ্বারা পিছনে ঠেলে দেওয়া হয়। SpatialDialog এখনও ব্যবহার করা যেতে পারে যখন স্থানিকীকরণও সক্ষম না হয়, এবং এটি তার 2D প্রতিরূপ: 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")
               }
           }
       }
   }
}

কোড সম্পর্কে মূল পয়েন্ট

কাস্টম প্যানেল এবং লেআউট তৈরি করুন

XR-এর জন্য রচনা দ্বারা সমর্থিত নয় এমন কাস্টম প্যানেল তৈরি করতে, আপনি SceneCore API ব্যবহার করে সরাসরি PanelEntities এবং দৃশ্য গ্রাফের সাথে কাজ করতে পারেন।

এছাড়াও দেখুন