কম্পোজে ভিউ ব্যবহার করা

আপনি একটি রচনা UI এ একটি Android ভিউ অনুক্রম অন্তর্ভুক্ত করতে পারেন৷ এই পদ্ধতিটি বিশেষভাবে উপযোগী যদি আপনি UI উপাদানগুলি ব্যবহার করতে চান যা এখনও রচনায় উপলব্ধ নয়, যেমন AdView । এই পদ্ধতিটি আপনাকে আপনার ডিজাইন করা কাস্টম ভিউ পুনরায় ব্যবহার করতে দেয়।

একটি ভিউ উপাদান বা অনুক্রম অন্তর্ভুক্ত করতে, AndroidView কম্পোজেবল ব্যবহার করুন। AndroidView একটি ল্যাম্বডা পাস করা হয় যা একটি View প্রদান করে। AndroidView একটি update কলব্যাক প্রদান করে যা ভিউ স্ফীত হলে কল করা হয়। যখনই কলব্যাকের মধ্যে একটি State পড়া পরিবর্তন হয় তখন AndroidView পুনরায় সংকলন করে। AndroidView , অন্যান্য অনেক বিল্ট-ইন কম্পোজেবলের মতো, একটি Modifier প্যারামিটার নেয় যা ব্যবহার করা যেতে পারে, উদাহরণস্বরূপ, প্যারেন্ট কম্পোজেবলে এর অবস্থান সেট করতে।

@Composable
fun CustomView() {
    var selectedItem by remember { mutableStateOf(0) }

    // Adds view to Compose
    AndroidView(
        modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree
        factory = { context ->
            // Creates view
            MyView(context).apply {
                // Sets up listeners for View -> Compose communication
                setOnClickListener {
                    selectedItem = 1
                }
            }
        },
        update = { view ->
            // View's been inflated or state read in this block has been updated
            // Add logic here if necessary

            // As selectedItem is read here, AndroidView will recompose
            // whenever the state changes
            // Example of Compose -> View communication
            view.selectedItem = selectedItem
        }
    )
}

@Composable
fun ContentExample() {
    Column(Modifier.fillMaxSize()) {
        Text("Look at this CustomView!")
        CustomView()
    }
}

ভিউ বাইন্ডিং সহ AndroidView

একটি XML লেআউট এম্বেড করতে, AndroidViewBinding API ব্যবহার করুন, যা androidx.compose.ui:ui-viewbinding লাইব্রেরি দ্বারা সরবরাহ করা হয়। এটি করার জন্য, আপনার প্রকল্পটি অবশ্যই ভিউ বাইন্ডিং সক্ষম করবে।

@Composable
fun AndroidViewBindingExample() {
    AndroidViewBinding(ExampleLayoutBinding::inflate) {
        exampleView.setBackgroundColor(Color.GRAY)
    }
}

অলস তালিকায় AndroidView

আপনি যদি অলস তালিকায় একটি AndroidView ব্যবহার করেন ( LazyColumn , LazyRow , Pager , ইত্যাদি), সংস্করণ 1.4.0-rc01-এ চালু করা AndroidView ওভারলোড ব্যবহার করার কথা বিবেচনা করুন৷ এই ওভারলোড কম্পোজকে অন্তর্নিহিত View ইন্সট্যান্স পুনঃব্যবহারের অনুমতি দেয় যখন অলস তালিকার ক্ষেত্রে ধারণকৃত রচনাটি পুনরায় ব্যবহার করা হয়।

AndroidView এর এই ওভারলোড 2টি অতিরিক্ত প্যারামিটার যোগ করে:

  • onReset - একটি কলব্যাক যা সংকেত দিতে আহ্বান করা হয়েছে যে View পুনরায় ব্যবহার করা হবে। দেখুন পুনঃব্যবহার সক্ষম করতে এটি অবশ্যই নন-নাল হতে হবে।
  • onRelease (ঐচ্ছিক) - একটি কলব্যাক যা সংকেত দিতে আহ্বান করা হয়েছে যে View রচনা থেকে প্রস্থান করেছে এবং পুনরায় ব্যবহার করা হবে না।

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun AndroidViewInLazyList() {
    LazyColumn {
        items(100) { index ->
            AndroidView(
                modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree
                factory = { context ->
                    MyView(context)
                },
                update = { view ->
                    view.selectedItem = index
                },
                onReset = { view ->
                    view.clear()
                }
            )
        }
    }
}

রচনায় টুকরা

কম্পোজে একটি Fragment যোগ করতে কম্পোজযোগ্য AndroidViewBinding ব্যবহার করুন। AndroidViewBinding ফ্র্যাগমেন্ট-নির্দিষ্ট হ্যান্ডলিং আছে যেমন কম্পোজেবল কম্পোজিশন ছেড়ে দিলে খণ্ডটি সরানো।

আপনার Fragment ধারক হিসাবে একটি FragmentContainerView সম্বলিত একটি XML স্ফীত করে এটি করুন৷

উদাহরণস্বরূপ, যদি আপনার my_fragment_layout.xml সংজ্ঞায়িত থাকে, তাহলে আপনি আপনার Fragment ক্লাসের নামের সাথে android:name XML অ্যাট্রিবিউট প্রতিস্থাপন করার সময় এইরকম কোড ব্যবহার করতে পারেন:

<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.example.compose.snippets.interop.MyFragment" />

নিম্নরূপ রচনায় এই খণ্ডটি স্ফীত করুন:

@Composable
fun FragmentInComposeExample() {
    AndroidViewBinding(MyFragmentLayoutBinding::inflate) {
        val myFragment = fragmentContainerView.getFragment<MyFragment>()
        // ...
    }
}

আপনি যদি একই লেআউটে একাধিক খণ্ড ব্যবহার করতে চান, তাহলে নিশ্চিত করুন যে আপনি প্রতিটি FragmentContainerView এর জন্য একটি অনন্য ID সংজ্ঞায়িত করেছেন।

কম্পোজ থেকে অ্যান্ড্রয়েড ফ্রেমওয়ার্ক কল করা হচ্ছে

কম্পোজ অ্যান্ড্রয়েড ফ্রেমওয়ার্ক ক্লাসের মধ্যে কাজ করে। উদাহরণস্বরূপ, এটি Activity বা Fragment মতো অ্যান্ড্রয়েড ভিউ ক্লাসে হোস্ট করা হয়েছে এবং Context , সিস্টেম রিসোর্স, Service বা BroadcastReceiver মতো অ্যান্ড্রয়েড ফ্রেমওয়ার্ক ক্লাস ব্যবহার করতে পারে।

সিস্টেম রিসোর্স সম্পর্কে আরও জানতে, কম্পোজ এ রিসোর্স দেখুন।

রচনা স্থানীয়দের

CompositionLocal ক্লাসগুলি কম্পোজযোগ্য ফাংশনের মাধ্যমে অন্তর্নিহিতভাবে ডেটা পাস করার অনুমতি দেয়। এগুলি সাধারণত UI গাছের একটি নির্দিষ্ট নোডে একটি মান দিয়ে সরবরাহ করা হয়। কম্পোজেবল ফাংশনে CompositionLocal প্যারামিটার হিসেবে ঘোষণা না করেই সেই মানটি তার কম্পোজযোগ্য বংশধরদের দ্বারা ব্যবহার করা যেতে পারে।

CompositionLocal কম্পোজে Android ফ্রেমওয়ার্কের ধরনগুলির জন্য মানগুলি প্রচার করতে ব্যবহৃত হয় যেমন Context , Configuration বা সেই View যেখানে কম্পোজ কোডটি সংশ্লিষ্ট LocalContext , LocalConfiguration , বা LocalView এর সাথে হোস্ট করা হয়। মনে রাখবেন যে আইডিই-তে স্বয়ংসম্পূর্ণ হওয়ার সাথে আরও ভাল আবিষ্কারের জন্য CompositionLocal ক্লাসগুলিকে Local এর সাথে প্রিফিক্স করা হয়েছে।

একটি CompositionLocal এর current সম্পত্তি ব্যবহার করে বর্তমান মান অ্যাক্সেস করুন। উদাহরণস্বরূপ, নীচের কোডটি Toast.makeToast পদ্ধতিতে LocalContext.current প্রদান করে একটি টোস্ট বার্তা দেখায়।

@Composable
fun ToastGreetingButton(greeting: String) {
    val context = LocalContext.current
    Button(onClick = {
        Toast.makeText(context, greeting, Toast.LENGTH_SHORT).show()
    }) {
        Text("Greet")
    }
}

আরও সম্পূর্ণ উদাহরণের জন্য, এই নথির শেষে কেস স্টাডি: BroadcastReceivers বিভাগটি দেখুন।

অন্যান্য মিথস্ক্রিয়া

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

class OtherInteractionsActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // get data from savedInstanceState
        setContent {
            MaterialTheme {
                ExampleComposable(data, onButtonClick = {
                    startActivity(Intent(this, MyActivity::class.java))
                })
            }
        }
    }
}

@Composable
fun ExampleComposable(data: DataExample, onButtonClick: () -> Unit) {
    Button(onClick = onButtonClick) {
        Text(data.title)
    }
}

কেস স্টাডি: ব্রডকাস্ট রিসিভার

বৈশিষ্ট্যগুলির আরও বাস্তবসম্মত উদাহরণের জন্য আপনি কম্পোজে স্থানান্তরিত করতে বা প্রয়োগ করতে চান এবং CompositionLocal এবং পার্শ্ব প্রতিক্রিয়া প্রদর্শন করতে চান, ধরা যাক একটি BroadcastReceiver একটি সংমিশ্রণযোগ্য ফাংশন থেকে নিবন্ধিত করা প্রয়োজন৷

সমাধানটি বর্তমান প্রসঙ্গ ব্যবহার করার জন্য LocalContext ব্যবহার করে এবং UpdatedState এবং DisposableEffect পার্শ্বপ্রতিক্রিয়া rememberUpdatedState

@Composable
fun SystemBroadcastReceiver(
    systemAction: String,
    onSystemEvent: (intent: Intent?) -> Unit
) {
    // Grab the current context in this part of the UI tree
    val context = LocalContext.current

    // Safely use the latest onSystemEvent lambda passed to the function
    val currentOnSystemEvent by rememberUpdatedState(onSystemEvent)

    // If either context or systemAction changes, unregister and register again
    DisposableEffect(context, systemAction) {
        val intentFilter = IntentFilter(systemAction)
        val broadcast = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                currentOnSystemEvent(intent)
            }
        }

        context.registerReceiver(broadcast, intentFilter)

        // When the effect leaves the Composition, remove the callback
        onDispose {
            context.unregisterReceiver(broadcast)
        }
    }
}

@Composable
fun HomeScreen() {

    SystemBroadcastReceiver(Intent.ACTION_BATTERY_CHANGED) { batteryStatus ->
        val isCharging = /* Get from batteryStatus ... */ true
        /* Do something if the device is charging */
    }

    /* Rest of the HomeScreen */
}

পরবর্তী পদক্ষেপ

এখন যেহেতু আপনি দৃশ্যে রচনা করার সময় এবং এর বিপরীতে ব্যবহার করার সময় ইন্টারঅপারেবিলিটি APIগুলি জানেন, আরও জানতে অন্যান্য বিবেচনার পৃষ্ঠাটি অন্বেষণ করুন৷

{% শব্দার্থে %} {% endverbatim %} {% শব্দার্থে %} {% endverbatim %} ,

আপনি একটি রচনা UI এ একটি Android ভিউ অনুক্রম অন্তর্ভুক্ত করতে পারেন৷ এই পদ্ধতিটি বিশেষভাবে উপযোগী যদি আপনি UI উপাদানগুলি ব্যবহার করতে চান যা এখনও রচনায় উপলব্ধ নয়, যেমন AdView । এই পদ্ধতিটি আপনাকে আপনার ডিজাইন করা কাস্টম ভিউ পুনরায় ব্যবহার করতে দেয়।

একটি ভিউ উপাদান বা অনুক্রম অন্তর্ভুক্ত করতে, AndroidView কম্পোজেবল ব্যবহার করুন। AndroidView একটি ল্যাম্বডা পাস করা হয় যা একটি View প্রদান করে। AndroidView একটি update কলব্যাক প্রদান করে যা ভিউ স্ফীত হলে কল করা হয়। যখনই কলব্যাকের মধ্যে একটি State পড়া পরিবর্তন হয় তখন AndroidView পুনরায় সংকলন করে। AndroidView , অন্যান্য অনেক বিল্ট-ইন কম্পোজেবলের মতো, একটি Modifier প্যারামিটার নেয় যা ব্যবহার করা যেতে পারে, উদাহরণস্বরূপ, প্যারেন্ট কম্পোজেবলে এর অবস্থান সেট করতে।

@Composable
fun CustomView() {
    var selectedItem by remember { mutableStateOf(0) }

    // Adds view to Compose
    AndroidView(
        modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree
        factory = { context ->
            // Creates view
            MyView(context).apply {
                // Sets up listeners for View -> Compose communication
                setOnClickListener {
                    selectedItem = 1
                }
            }
        },
        update = { view ->
            // View's been inflated or state read in this block has been updated
            // Add logic here if necessary

            // As selectedItem is read here, AndroidView will recompose
            // whenever the state changes
            // Example of Compose -> View communication
            view.selectedItem = selectedItem
        }
    )
}

@Composable
fun ContentExample() {
    Column(Modifier.fillMaxSize()) {
        Text("Look at this CustomView!")
        CustomView()
    }
}

ভিউ বাইন্ডিং সহ AndroidView

একটি XML লেআউট এম্বেড করতে, AndroidViewBinding API ব্যবহার করুন, যা androidx.compose.ui:ui-viewbinding লাইব্রেরি দ্বারা সরবরাহ করা হয়। এটি করার জন্য, আপনার প্রকল্পটি অবশ্যই ভিউ বাইন্ডিং সক্ষম করবে।

@Composable
fun AndroidViewBindingExample() {
    AndroidViewBinding(ExampleLayoutBinding::inflate) {
        exampleView.setBackgroundColor(Color.GRAY)
    }
}

অলস তালিকায় AndroidView

আপনি যদি অলস তালিকায় একটি AndroidView ব্যবহার করেন ( LazyColumn , LazyRow , Pager , ইত্যাদি), সংস্করণ 1.4.0-rc01-এ চালু করা AndroidView ওভারলোড ব্যবহার করার কথা বিবেচনা করুন৷ এই ওভারলোড কম্পোজকে অন্তর্নিহিত View ইন্সট্যান্স পুনঃব্যবহারের অনুমতি দেয় যখন অলস তালিকার ক্ষেত্রে ধারণকৃত রচনাটি পুনরায় ব্যবহার করা হয়।

AndroidView এর এই ওভারলোড 2টি অতিরিক্ত প্যারামিটার যোগ করে:

  • onReset - একটি কলব্যাক যা সংকেত দিতে আহ্বান করা হয়েছে যে View পুনরায় ব্যবহার করা হবে। দেখুন পুনঃব্যবহার সক্ষম করতে এটি অবশ্যই নন-নাল হতে হবে।
  • onRelease (ঐচ্ছিক) - একটি কলব্যাক যা সংকেত দিতে আহ্বান করা হয়েছে যে View রচনা থেকে প্রস্থান করেছে এবং পুনরায় ব্যবহার করা হবে না।

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun AndroidViewInLazyList() {
    LazyColumn {
        items(100) { index ->
            AndroidView(
                modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree
                factory = { context ->
                    MyView(context)
                },
                update = { view ->
                    view.selectedItem = index
                },
                onReset = { view ->
                    view.clear()
                }
            )
        }
    }
}

রচনায় টুকরা

কম্পোজে একটি Fragment যোগ করতে কম্পোজযোগ্য AndroidViewBinding ব্যবহার করুন। AndroidViewBinding ফ্র্যাগমেন্ট-নির্দিষ্ট হ্যান্ডলিং আছে যেমন কম্পোজেবল কম্পোজিশন ছেড়ে দিলে খণ্ডটি সরানো।

আপনার Fragment ধারক হিসাবে একটি FragmentContainerView সম্বলিত একটি XML স্ফীত করে এটি করুন৷

উদাহরণস্বরূপ, যদি আপনার my_fragment_layout.xml সংজ্ঞায়িত থাকে, তাহলে আপনি আপনার Fragment ক্লাসের নামের সাথে android:name XML অ্যাট্রিবিউট প্রতিস্থাপন করার সময় এইরকম কোড ব্যবহার করতে পারেন:

<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.example.compose.snippets.interop.MyFragment" />

নিম্নরূপ রচনায় এই খণ্ডটি স্ফীত করুন:

@Composable
fun FragmentInComposeExample() {
    AndroidViewBinding(MyFragmentLayoutBinding::inflate) {
        val myFragment = fragmentContainerView.getFragment<MyFragment>()
        // ...
    }
}

আপনি যদি একই লেআউটে একাধিক খণ্ড ব্যবহার করতে চান, তাহলে নিশ্চিত করুন যে আপনি প্রতিটি FragmentContainerView এর জন্য একটি অনন্য ID সংজ্ঞায়িত করেছেন।

কম্পোজ থেকে অ্যান্ড্রয়েড ফ্রেমওয়ার্ক কল করা হচ্ছে

কম্পোজ অ্যান্ড্রয়েড ফ্রেমওয়ার্ক ক্লাসের মধ্যে কাজ করে। উদাহরণস্বরূপ, এটি Activity বা Fragment মতো অ্যান্ড্রয়েড ভিউ ক্লাসে হোস্ট করা হয়েছে এবং Context , সিস্টেম রিসোর্স, Service বা BroadcastReceiver মতো অ্যান্ড্রয়েড ফ্রেমওয়ার্ক ক্লাস ব্যবহার করতে পারে।

সিস্টেম রিসোর্স সম্পর্কে আরও জানতে, কম্পোজ এ রিসোর্স দেখুন।

রচনা স্থানীয়দের

CompositionLocal ক্লাসগুলি কম্পোজযোগ্য ফাংশনের মাধ্যমে অন্তর্নিহিতভাবে ডেটা পাস করার অনুমতি দেয়। এগুলি সাধারণত UI গাছের একটি নির্দিষ্ট নোডে একটি মান দিয়ে সরবরাহ করা হয়। কম্পোজেবল ফাংশনে CompositionLocal প্যারামিটার হিসেবে ঘোষণা না করেই সেই মানটি তার কম্পোজযোগ্য বংশধরদের দ্বারা ব্যবহার করা যেতে পারে।

CompositionLocal কম্পোজে Android ফ্রেমওয়ার্কের ধরনগুলির জন্য মানগুলি প্রচার করতে ব্যবহৃত হয় যেমন Context , Configuration বা সেই View যেখানে কম্পোজ কোডটি সংশ্লিষ্ট LocalContext , LocalConfiguration , বা LocalView এর সাথে হোস্ট করা হয়। মনে রাখবেন যে আইডিই-তে স্বয়ংসম্পূর্ণ হওয়ার সাথে আরও ভাল আবিষ্কারের জন্য CompositionLocal ক্লাসগুলিকে Local এর সাথে প্রিফিক্স করা হয়েছে।

একটি CompositionLocal এর current সম্পত্তি ব্যবহার করে বর্তমান মান অ্যাক্সেস করুন। উদাহরণস্বরূপ, নীচের কোডটি Toast.makeToast পদ্ধতিতে LocalContext.current প্রদান করে একটি টোস্ট বার্তা দেখায়।

@Composable
fun ToastGreetingButton(greeting: String) {
    val context = LocalContext.current
    Button(onClick = {
        Toast.makeText(context, greeting, Toast.LENGTH_SHORT).show()
    }) {
        Text("Greet")
    }
}

আরও সম্পূর্ণ উদাহরণের জন্য, এই নথির শেষে কেস স্টাডি: BroadcastReceivers বিভাগটি দেখুন।

অন্যান্য মিথস্ক্রিয়া

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

class OtherInteractionsActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // get data from savedInstanceState
        setContent {
            MaterialTheme {
                ExampleComposable(data, onButtonClick = {
                    startActivity(Intent(this, MyActivity::class.java))
                })
            }
        }
    }
}

@Composable
fun ExampleComposable(data: DataExample, onButtonClick: () -> Unit) {
    Button(onClick = onButtonClick) {
        Text(data.title)
    }
}

কেস স্টাডি: ব্রডকাস্ট রিসিভার

বৈশিষ্ট্যগুলির আরও বাস্তবসম্মত উদাহরণের জন্য আপনি কম্পোজে স্থানান্তরিত করতে বা প্রয়োগ করতে চান এবং CompositionLocal এবং পার্শ্ব প্রতিক্রিয়া প্রদর্শন করতে চান, ধরা যাক একটি BroadcastReceiver একটি সংমিশ্রণযোগ্য ফাংশন থেকে নিবন্ধিত করা প্রয়োজন৷

সমাধানটি বর্তমান প্রসঙ্গ ব্যবহার করার জন্য LocalContext ব্যবহার করে এবং UpdatedState এবং DisposableEffect পার্শ্বপ্রতিক্রিয়া rememberUpdatedState

@Composable
fun SystemBroadcastReceiver(
    systemAction: String,
    onSystemEvent: (intent: Intent?) -> Unit
) {
    // Grab the current context in this part of the UI tree
    val context = LocalContext.current

    // Safely use the latest onSystemEvent lambda passed to the function
    val currentOnSystemEvent by rememberUpdatedState(onSystemEvent)

    // If either context or systemAction changes, unregister and register again
    DisposableEffect(context, systemAction) {
        val intentFilter = IntentFilter(systemAction)
        val broadcast = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                currentOnSystemEvent(intent)
            }
        }

        context.registerReceiver(broadcast, intentFilter)

        // When the effect leaves the Composition, remove the callback
        onDispose {
            context.unregisterReceiver(broadcast)
        }
    }
}

@Composable
fun HomeScreen() {

    SystemBroadcastReceiver(Intent.ACTION_BATTERY_CHANGED) { batteryStatus ->
        val isCharging = /* Get from batteryStatus ... */ true
        /* Do something if the device is charging */
    }

    /* Rest of the HomeScreen */
}

পরবর্তী পদক্ষেপ

এখন যেহেতু আপনি আন্তঃঅপারেবিলিটি APIগুলি জানেন যখন দৃশ্যে রচনা করুন এবং এর বিপরীতে, আরও জানতে অন্যান্য বিবেচনার পৃষ্ঠাটি অন্বেষণ করুন৷

{% শব্দার্থে %} {% endverbatim %} {% শব্দার্থে %} {% endverbatim %}