Compose यूज़र इंटरफ़ेस (यूआई) में, Android व्यू हैरारकी को शामिल किया जा सकता है. यह तरीका खास तौर पर तब काम आता है, जब आपको ऐसे यूज़र इंटरफ़ेस (यूआई) एलिमेंट इस्तेमाल करने हों जो फ़िलहाल 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 व्यू बाइंडिंग के साथ
एक्सएमएल लेआउट को एम्बेड करने के लिए, AndroidViewBinding एपीआई का इस्तेमाल करें. यह 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 ओवरलोड का इस्तेमाल करें. इस ओवरलोड की मदद से, Compose, View इंस्टेंस का फिर से इस्तेमाल कर सकता है. ऐसा तब होता है, जब कंपोज़िशन को फिर से इस्तेमाल किया जाता है. जैसे, लेज़ी लिस्ट के लिए.
AndroidView के इस ओवरलोड में दो अतिरिक्त पैरामीटर जोड़े गए हैं:
onReset- यह एक कॉलबैक है. इसे तब शुरू किया जाता है, जबViewको फिर से इस्तेमाल किया जाना हो. व्यू को फिर से इस्तेमाल करने की सुविधा चालू करने के लिए, यह वैल्यू 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 में फ़्रैगमेंट (ट्रांज़िशनरी चरण)
Compose में Fragment जोड़ने के लिए, AndroidFragment कंपोज़ेबल का इस्तेमाल करें.
AndroidFragment में फ़्रैगमेंट के हिसाब से हैंडलिंग होती है. जैसे, कंपोज़ेबल के कंपोज़िशन से बाहर निकलने पर फ़्रैगमेंट को हटाना.
किसी फ़्रैगमेंट को शामिल करने के लिए, AndroidFragment कंपोज़ेबल का इस्तेमाल करें. Fragment क्लास को AndroidFragment में पास किया जाता है. इसके बाद, उस क्लास का एक इंस्टेंस सीधे कंपोज़िशन में जोड़ता है. AndroidFragment, fragmentState ऑब्जेक्ट भी उपलब्ध कराता है. इसका इस्तेमाल करके, AndroidFragment को किसी तय स्थिति में बनाया जा सकता है. साथ ही, arguments का इस्तेमाल करके, इसे नए फ़्रैगमेंट में पास किया जा सकता है. इसके अलावा, onUpdate कॉलबैक का इस्तेमाल करके, कंपोज़िशन से फ़्रैगमेंट उपलब्ध कराया जा सकता है. कई अन्य बिल्ट-इन कंपोज़ेबल की तरह, AndroidFragment भी एक Modifier पैरामीटर स्वीकार करता है. इसका इस्तेमाल किया जा सकता है. उदाहरण के लिए, पैरंट कंपोज़ेबल में इसकी पोज़िशन सेट करने के लिए.
'लिखें' में जाकर, AndroidFragment को इस तरह कॉल करें:
@Composable fun FragmentInComposeExample() { AndroidFragment<MyFragment>() }
कैप फ़्रैगमेंट लाइफ़साइकल की स्थिति
Fragment 1.9.0 और इसके बाद के वर्शन में, एम्बेड किए गए Fragment की लाइफ़साइकल स्थिति को सीमित करने के लिए, maxLifecycle
पैरामीटर का इस्तेमाल किया जा सकता है.
उदाहरण के लिए, किसी HorizontalPager में, maxLifecycle को डाइनैमिक तरीके से RESUMED पर सिर्फ़ तब सेट किया जा सकता है, जब उससे जुड़ा पेज चालू हो. साथ ही, स्क्रीन पर न दिखने वाले पेजों को STARTED पर सेट किया जा सकता है. जब उपयोगकर्ता किसी दूसरे पेज पर जाता है, तो पिछले पेज के फ़्रैगमेंट कैप की वैल्यू STARTED हो जाती है. इससे RESUMED के स्कोप वाले वर्कलोड रुक जाते हैं या रद्द हो जाते हैं. जैसे, repeatOnLifecycle(RESUMED) में चल रही कोरूटीन. इससे, स्क्रीन पर न दिखने वाले पेजों को सिर्फ़ फ़ोरग्राउंड में काम करने से रोका जा सकता है. साथ ही, उनके यूज़र इंटरफ़ेस (यूआई) को STARTED पर चालू रखा जा सकता है:
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 View क्लास पर होस्ट किया जाता है. जैसे, Activity या Fragment. साथ ही, यह Android फ़्रेमवर्क क्लास का इस्तेमाल कर सकता है. जैसे, Context, सिस्टम रिसॉर्स, Service या BroadcastReceiver.
सिस्टम संसाधनों के बारे में ज़्यादा जानने के लिए, Compose में संसाधन देखें.
कंपोज़िशन के लोकल
CompositionLocal
क्लास की मदद से, कंपोज़ेबल फ़ंक्शन के ज़रिए डेटा को इंप्लिसिट तौर पर पास किया जा सकता है. आम तौर पर, इन्हें यूज़र इंटरफ़ेस (यूआई) ट्री के किसी नोड में वैल्यू के साथ दिया जाता है. इस वैल्यू का इस्तेमाल, कंपोज़ किए जा सकने वाले डिसेंडेंट कर सकते हैं. इसके लिए, कंपोज़ किए जा सकने वाले फ़ंक्शन में CompositionLocal को पैरामीटर के तौर पर एलान करने की ज़रूरत नहीं होती.
CompositionLocal का इस्तेमाल, Compose में Android फ़्रेमवर्क टाइप के लिए वैल्यू को आगे बढ़ाने के लिए किया जाता है. जैसे, Context, Configuration या View, जिसमें Compose कोड को 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") } }
ब्रॉडकास्ट रिसीवर
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 के सामान्य दिशा-निर्देश का पालन करें. इसके मुताबिक, डेटा नीचे की ओर जाता है और इवेंट ऊपर की ओर जाते हैं. इसके बारे में 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) } }