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

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

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

লেজি লিস্টে AndroidView

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

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

  • onReset - View পুনরায় ব্যবহার করা হবে তা বোঝানোর জন্য ব্যবহৃত একটি কলব্যাক। ভিউয়ের পুনঃব্যবহার সক্ষম করতে এটি অবশ্যই নন-নাল (non-null) হতে হবে।
  • 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 একটি fragmentState অবজেক্টও প্রদান করে, যা একটি নির্দিষ্ট স্টেট সহ AndroidFragment তৈরি করতে, নতুন ফ্র্যাগমেন্টে পাস করার জন্য arguments এবং একটি onUpdate কলব্যাক সরবরাহ করে, যা কম্পোজিশন থেকে ফ্র্যাগমেন্টটি প্রদান করে। অন্যান্য অনেক বিল্ট-ইন কম্পোজেবলের মতো, AndroidFragment একটি Modifier প্যারামিটার গ্রহণ করে, যা আপনি ব্যবহার করতে পারেন, উদাহরণস্বরূপ, প্যারেন্ট কম্পোজেবলে এর অবস্থান নির্ধারণ করার জন্য।

Compose-এ AndroidFragment নিম্নোক্তভাবে কল করুন:

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

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

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

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

গঠন স্থানীয়

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

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

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

আপনার প্রয়োজনীয় ইন্টারঅ্যাকশনের জন্য যদি কোনো ইউটিলিটি সংজ্ঞায়িত না থাকে, তবে সবচেয়ে ভালো উপায় হলো 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)
    }
}