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

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

ভিউ এলিমেন্ট বা হায়ারার্কি অন্তর্ভুক্ত করতে, AndroidView কম্পোজ করার উপযুক্ত আইটেম ব্যবহার করুন। AndroidView-এ এমন একটি ল্যাম্বডা পাস করা হয় যা a 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 লেআউট এম্বেড করতে, androidx.compose.ui:ui-viewbinding লাইব্রেরির দেওয়া AndroidViewBinding API ব্যবহার করুন। এটি করতে, আপনার প্রোজেক্টে ভিউ বাইন্ডিং চালু থাকতে হবে।

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

Lazy তালিকায় AndroidView নম্বর

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

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-এ ফ্র্যাগমেন্ট (পরিবর্তনমূলক ধাপ)

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

কোনও ফ্র্যাগমেন্ট অন্তর্ভুক্ত করতে, AndroidFragment কম্পোজ করার উপযুক্ত আইটেম ব্যবহার করুন। আপনি Fragment ক্লাসকে AndroidFragment-এ পাস করেন, যা তারপরে কম্পোজিশনে সরাসরি সেই ক্লাসের একটি ইনস্ট্যান্স যোগ করে। AndroidFragment এছাড়াও একটি fragmentState অবজেক্ট প্রদান করে যা প্রদত্ত স্টেট সহ AndroidFragment তৈরি করে, 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 ফ্রেমওয়ার্ক ক্লাসের মধ্যে কাজ করে। যেমন, এটি Activity বা Fragment-এর মতো Android View ক্লাসে হোস্ট করা হয় এবং Context, সিস্টেম রিসোর্স, Service বা BroadcastReceiver-এর মতো Android ফ্রেমওয়ার্ক ক্লাস ব্যবহার করতে পারে।

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

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

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

CompositionLocal-এর মাধ্যমে Compose-এ Android ফ্রেমওয়ার্কের জন্য ভ্যালু প্রোপাগেট করা হয়। যেমন, Context, Configuration অথবা View, যেখানে Compose কোড হোস্ট করা হয় এবং তার সাথে সংশ্লিষ্ট LocalContext, LocalConfiguration, বা LocalView থাকে। মনে রাখবেন, IDE-তে অটো-কমপ্লিট ফিচারের মাধ্যমে আরও ভালভাবে খুঁজে পাওয়ার জন্য 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")
    }
}

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

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

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

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

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