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

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

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

@Composable
fun CustomView() {
    var selectedItem by remember { mutableIntStateOf(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)
    }
}

Lazy lists-এ AndroidView

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

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

  • onReset - View আবার ব্যবহার করা হবে বলে সিগন্যাল দেওয়ার জন্য কলব্যাক ইনভোক করা হয়েছে। ভিউ আবার ব্যবহার করার সুবিধা চালু করতে এটি নন-নাল হতে হবে।
  • onRelease (ঐচ্ছিক) - View কম্পোজিশন থেকে বেরিয়ে গেছে এবং আর ব্যবহার করা হবে না, এই সিগন্যাল দেওয়ার জন্য কলব্যাক ইনভোক করা হয়েছে।

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

কম্পোজে ফ্র্যাগমেন্ট (ট্রানজিশনারি ধাপ)

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

ফ্র্যাগমেন্ট অন্তর্ভুক্ত করতে, AndroidFragment কম্পোজেবল ব্যবহার করুন। আপনি AndroidFragment-এ Fragment ক্লাস পাস করেন, যা পরে কম্পোজিশনে সরাসরি সেই ক্লাসের একটি ইনস্ট্যান্স যোগ করে। এছাড়াও, AndroidFragment প্রদত্ত স্টেট সহ AndroidFragment তৈরি করার জন্য fragmentState অবজেক্ট, নতুন ফ্র্যাগমেন্টে পাস করার জন্য arguments এবং কম্পোজিশন থেকে ফ্র্যাগমেন্ট প্রদান করে এমন onUpdate কলব্যাক প্রদান করে। অন্যান্য অনেক বিল্ট-ইন কম্পোজেবলের মতো, AndroidFragment একটি Modifier প্যারামিটার গ্রহণ করে যা আপনি ব্যবহার করতে পারেন, উদাহরণস্বরূপ, পেরেন্ট কম্পোজেবলে এর পজিশন সেট করতে।

Compose-এ AndroidFragment-কে এইভাবে কল করুন:

@Composable
fun FragmentInComposeExample() {
    AndroidFragment<MyFragment>()
}

ক্যাপ ফ্র্যাগমেন্ট লাইফসাইকেল স্টেট

Fragment 1.9.0 এবং তার পরবর্তী ভার্সনে, আপনি এম্বেড করা Fragment-এর লাইফসাইকেল স্টেট ক্যাপ করতে maxLifecycle প্যারামিটার ব্যবহার করতে পারবেন।

যেমন, HorizontalPager-এ, আপনি ডাইনামিকভাবে maxLifecycle-কে RESUMED-এ সেট করতে পারবেন, শুধুমাত্র যখন সংশ্লিষ্ট পৃষ্ঠাটি অ্যাক্টিভ থাকে, অফস্ক্রিন পৃষ্ঠাগুলি STARTED-এ সীমাবদ্ধ থাকে। ব্যবহারকারী অন্য পৃষ্ঠায় নেভিগেট করলে, আগের পৃষ্ঠার ফ্র্যাগমেন্ট ক্যাপ STARTED হয়ে যায়। এটি RESUMED-এ স্কোপ করা ওয়ার্কলোড পজ বা বাতিল করে (যেমন repeatOnLifecycle(RESUMED)-এ চলা কোরুটিন), অফস্ক্রিন পৃষ্ঠাগুলিকে শুধুমাত্র ফোরগ্রাউন্ডে কাজ করা থেকে আটকায়, যদিও STARTED-এ তাদের UI ইনিশিয়ালাইজ করা থাকে:

HorizontalPager(state = pagerState) { page ->
    // Dynamically cap the lifecycle state based on whether the page is selected
    val maxLifecycle = if (pagerState.settledPage == page) {
        Lifecycle.State.RESUMED
    } else {
        Lifecycle.State.STARTED
    }

    when (page) {
        0 -> AndroidFragment<HomeFragment>(maxLifecycle = maxLifecycle)
        1 -> AndroidFragment<LibraryFragment>(maxLifecycle = maxLifecycle)
        /* Other pages and corresponding fragments */
    }
}

Compose থেকে Android ফ্রেমওয়ার্ক কল করা

Compose, Android ফ্রেমওয়ার্ক ক্লাসের মধ্যে কাজ করে। যেমন, এটি Android ভিউ ক্লাসে হোস্ট করা হয়, যেমন Activity বা Fragment এবং Context, সিস্টেম রিসোর্স, Service বা BroadcastReceiver-এর মতো Android ফ্রেমওয়ার্ক ক্লাস ব্যবহার করতে পারে।

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

কম্পোজিশন লোকাল

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

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

current প্রপার্টি ব্যবহার করে CompositionLocal-এর বর্তমান ভ্যালু অ্যাক্সেস করুন। যেমন, নিচের কোডটি 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")
    }
}

সম্প্রচার রিসিভার

CompositionLocal এবং সাইড এফেক্ট দেখানোর জন্য, যদি একটি BroadcastReceiver-কে একটি কম্পোজেবল ফাংশন থেকে রেজিস্টার করতে হয়, তাহলে বর্তমান প্রসঙ্গ ব্যবহার করতে LocalContext ব্যবহার করুন এবং rememberUpdatedState এবং DisposableEffect সাইড এফেক্ট।

@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 */
}

অন্যান্য ইন্টার‌্যাকশন

আপনার প্রয়োজনীয় ইন্টার‍্যাকশনের জন্য কোনও ইউটিলিটি নির্দিষ্ট করা না থাকলে, পেশাদার পদ্ধতি হল সাধারণ Compose নির্দেশিকা অনুসরণ করা, ডেটা নিচের দিকে ফ্লো করে, ইভেন্ট উপরের দিকে ফ্লো করে (Thinking in Compose-এ আরও বিস্তারিতভাবে আলোচনা করা হয়েছে)। যেমন, এই কম্পোজেবল অন্য একটি অ্যাক্টিভিটি লঞ্চ করে:

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