दूसरी ज़रूरी बातें

व्यू से 'लिखें' सुविधा पर माइग्रेट करते समय, यह पूरी तरह से यूज़र इंटरफ़ेस (यूआई) से जुड़ा होता है. हालांकि, डेटा को सुरक्षित तरीके से और ज़्यादा से ज़्यादा लोगों तक पहुंचाने के लिए, कई चीज़ों का ध्यान रखना पड़ता है. आपके व्यू-आधारित ऐप्लिकेशन को Compose में माइग्रेट करते समय, इस पेज पर दी गई कुछ बातों का ध्यान रखा जाता है.

अपने ऐप्लिकेशन की थीम को माइग्रेट करना

Android ऐप्लिकेशन की थीम बनाने के लिए मटीरियल डिज़ाइन सुझाया गया डिज़ाइन सिस्टम है.

व्यू-आधारित ऐप्लिकेशन के लिए, Material के तीन वर्शन उपलब्ध हैं:

  • AppCompat लाइब्रेरी (यानी Theme.AppCompat.*) का इस्तेमाल करके, Material Design 1
  • MDC-Android लाइब्रेरी (यानी Theme.MaterialComponents.*) का इस्तेमाल करने वाला मटीरियल डिज़ाइन 2
  • MDC-Android लाइब्रेरी (Theme.Material3.*) का इस्तेमाल करके, Material Design 3

Compose के ऐप्लिकेशन में मटीरियल के दो वर्शन उपलब्ध हैं:

  • Compose मटीरियल लाइब्रेरी का इस्तेमाल करके मटीरियल डिज़ाइन 2 (यानी androidx.compose.material.MaterialTheme)
  • Compose Material 3 लाइब्रेरी (androidx.compose.material3.MaterialTheme) का इस्तेमाल करके, Material Design 3

हमारा सुझाव है कि अगर आपके ऐप्लिकेशन का डिज़ाइन सिस्टम, नए वर्शन (Material 3) का इस्तेमाल करने की ज़रूरी शर्तें पूरी करता है, तो नए वर्शन का इस्तेमाल करें. डेटा को दूसरी जगह भेजने से जुड़ी गाइड, व्यू और Compose, दोनों के लिए उपलब्ध हैं:

Compose में नई स्क्रीन बनाते समय, यह पक्का करें कि Compose की Material लाइब्रेरी से यूज़र इंटरफ़ेस (यूआई) को दिखाने वाले किसी भी कॉम्पोनेंट से पहले, MaterialTheme लागू किया गया हो. भले ही, आपने Material Design के किसी भी वर्शन का इस्तेमाल किया हो. Material के कॉम्पोनेंट (Button, Text वगैरह), MaterialTheme के मौजूद होने पर ही काम करते हैं. इसके बिना, इनका व्यवहार तय नहीं होता.

सभी Jetpack Compose सैंपल, MaterialTheme के आधार पर बनाई गई कस्टम Compose थीम का इस्तेमाल करते हैं.

ज़्यादा जानने के लिए, Compose में सिस्टम डिज़ाइन करना और एक्सएमएल थीम को कंपोज़ में माइग्रेट करना देखें.

अगर आपने अपने ऐप्लिकेशन में नेविगेशन कॉम्पोनेंट का इस्तेमाल किया है, तो ज़्यादा जानकारी के लिए Compose का इस्तेमाल करके नेविगेट करना - इंटरऑपरेबिलिटी और Jetpack नेविगेशन को Compose नेविगेशन पर माइग्रेट करना लेख पढ़ें.

Compose/व्यू के यूज़र इंटरफ़ेस (यूआई) को टेस्ट करना

अपने ऐप्लिकेशन के कुछ हिस्सों को Compose में माइग्रेट करने के बाद, यह जांच करना ज़रूरी है कि आपने कुछ भी गलत तो नहीं किया है.

जब किसी गतिविधि या फ़्रैगमेंट में लिखें की सुविधा का इस्तेमाल किया जाता है, तो आपको ActivityScenarioRule के बजाय createAndroidComposeRule का इस्तेमाल करना होगा. createAndroidComposeRule, ActivityScenarioRule को ComposeTestRule के साथ इंटिग्रेट करता है. इससे, आपको एक ही समय में 'लिखें' और 'कोड देखें' की जांच करने की सुविधा मिलती है.

class MyActivityTest {
    @Rule
    @JvmField
    val composeTestRule = createAndroidComposeRule<MyActivity>()

    @Test
    fun testGreeting() {
        val greeting = InstrumentationRegistry.getInstrumentation()
            .targetContext.resources.getString(R.string.greeting)

        composeTestRule.onNodeWithText(greeting).assertIsDisplayed()
    }
}

टेस्टिंग के बारे में ज़्यादा जानने के लिए, Compose के लेआउट की जांच करना देखें. यूज़र इंटरफ़ेस (यूआई) टेस्टिंग फ़्रेमवर्क के साथ इंटरऑपरेबिलिटी (दूसरे सिस्टम के साथ काम करना) के लिए, Aspresso की मदद से इंटरऑपरेबिलिटी और UiAutomator की मदद से इंटरऑपरेबिलिटी (दूसरे सिस्टम के साथ काम करना) देखें.

Compose को अपने मौजूदा ऐप्लिकेशन आर्किटेक्चर के साथ इंटिग्रेट करना

एकतरफ़ा डेटा फ़्लो (यूडीएफ़) आर्किटेक्चर के पैटर्न, Compose के साथ आसानी से काम करते हैं. अगर ऐप्लिकेशन इसके बजाय, मॉडल व्यू प्रज़ेंटेशनर (एमवीपी) जैसे अन्य तरह के आर्किटेक्चर पैटर्न का इस्तेमाल करता है, तो हमारा सुझाव है कि आप 'लिखें' सुविधा का इस्तेमाल करने से पहले या इसका इस्तेमाल करते समय, यूज़र इंटरफ़ेस (यूआई) के उस हिस्से को यूडीएफ़ में माइग्रेट करें.

Compose में ViewModel का इस्तेमाल करना

अगर स्ट्रक्चर कॉम्पोनेंट ViewModel लाइब्रेरी का इस्तेमाल किया जाता है, तो viewModel() फ़ंक्शन को कॉल करके किसी भी कंपोज़ेबल से ViewModel को ऐक्सेस किया जा सकता है, जैसा कि Compose और अन्य लाइब्रेरी में बताया गया है.

Compose का इस्तेमाल करते समय, अलग-अलग कंपोज़ेबल में एक ही ViewModel टाइप का इस्तेमाल करते समय सावधानी बरतें. इसकी वजह यह है कि ViewModel एलिमेंट, व्यू-लाइफ़साइकल के स्कोप का पालन करता है. अगर नेविगेशन लाइब्रेरी का इस्तेमाल किया जाता है, तो स्कोप होस्ट ऐक्टिविटी, फ़्रैगमेंट या नेविगेशन ग्राफ़ होगा.

उदाहरण के लिए, अगर कंपोज़ेबल को किसी गतिविधि में होस्ट किया गया है, तो viewModel() हमेशा वही इंस्टेंस दिखाता है जिसे सिर्फ़ गतिविधि खत्म होने पर ही हटाया जाता है. यहां दिए गए उदाहरण में, एक ही उपयोगकर्ता ("user1") का दो बार स्वागत किया गया है. ऐसा इसलिए है, क्योंकि होस्ट गतिविधि के तहत सभी कंपोज़ेबल में एक ही GreetingViewModel इंस्टेंस का फिर से इस्तेमाल किया गया है. बनाए गए पहले ViewModel इंस्टेंस का इस्तेमाल, अन्य कॉम्पोज़ेबल में फिर से किया जाता है.

class GreetingActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MaterialTheme {
                Column {
                    GreetingScreen("user1")
                    GreetingScreen("user2")
                }
            }
        }
    }
}

@Composable
fun GreetingScreen(
    userId: String,
    viewModel: GreetingViewModel = viewModel(  
        factory = GreetingViewModelFactory(userId)  
    )
) {
    val messageUser by viewModel.message.observeAsState("")
    Text(messageUser)
}

class GreetingViewModel(private val userId: String) : ViewModel() {
    private val _message = MutableLiveData("Hi $userId")
    val message: LiveData<String> = _message
}

class GreetingViewModelFactory(private val userId: String) : ViewModelProvider.Factory {
    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return GreetingViewModel(userId) as T
    }
}

नेविगेशन ग्राफ़ में ViewModel एलिमेंट का स्कोप भी किया जाता है, इसलिए नेविगेशन ग्राफ़ में डेस्टिनेशन के तौर पर मौजूद कंपोज़ेबल में ViewModel का अलग इंस्टेंस होता है. इस मामले में, ViewModel का दायरा डेस्टिनेशन के लाइफ़साइकल तक सीमित होता है. साथ ही, डेस्टिनेशन को बैकस्टैक से हटाने पर, इसे मिटा दिया जाता है. यहां दिए गए उदाहरण में, जब उपयोगकर्ता प्रोफ़ाइल स्क्रीन पर जाता है, तो GreetingViewModel का एक नया इंस्टेंस बन जाता है.

@Composable
fun MyApp() {
    NavHost(rememberNavController(), startDestination = "profile/{userId}") {
        /* ... */
        composable("profile/{userId}") { backStackEntry ->
            GreetingScreen(backStackEntry.arguments?.getString("userId") ?: "")
        }
    }
}

राज्य की जानकारी का सोर्स

जब आप यूज़र इंटरफ़ेस (यूआई) के किसी एक हिस्से में 'लिखें' इस्तेमाल करते हैं, तो हो सकता है कि 'लिखें' और 'व्यू सिस्टम कोड' को डेटा शेयर करने की ज़रूरत पड़े. हमारा सुझाव है कि जब भी हो सके, आप शेयर किए गए उस स्टेटस को किसी ऐसी क्लास में एन्क्रिप्ट (सुरक्षित) करें जो दोनों प्लैटफ़ॉर्म में इस्तेमाल किए जाने वाले यूडीएफ़ के सबसे सही तरीकों का पालन करता हो. उदाहरण के लिए, ऐसे ViewModel में जो डेटा अपडेट करने के लिए, शेयर किए गए डेटा की एक स्ट्रीम दिखाता है.

हालांकि, अगर शेयर किया जाने वाला डेटा बदला जा सकता है या किसी यूज़र इंटरफ़ेस (यूआई) एलिमेंट से ज़्यादा जुड़ा है, तो ऐसा हमेशा नहीं किया जा सकता. ऐसे में, एक सिस्टम को सटीक डेटा का सोर्स होना चाहिए. साथ ही, उस सिस्टम को दूसरे सिस्टम के साथ डेटा अपडेट शेयर करने होंगे. आम तौर पर, सटीक जानकारी देने वाले सोर्स का मालिकाना हक, यूज़र इंटरफ़ेस (यूआई) के क्रम में सबसे ऊपर मौजूद एलिमेंट के पास होना चाहिए.

सटीक जानकारी के तौर पर कॉम्पोज़ करना

Compose स्टेटस को नॉन-Compose कोड में पब्लिश करने के लिए, SideEffect composable का इस्तेमाल करें. इस मामले में, ट्रुथ सोर्स को कंपोज़ेबल में रखा जाता है, जो स्थिति के बारे में अपडेट भेजता है.

उदाहरण के तौर पर, आपकी Analytics लाइब्रेरी आपको बाद के सभी Analytics इवेंट में कस्टम मेटाडेटा (इस उदाहरण में उपयोगकर्ता प्रॉपर्टी) अटैच करके, उपयोगकर्ताओं की जनसंख्या को सेगमेंट में बांटने की अनुमति दे सकती है. अपनी ऐनलिटिक्स लाइब्रेरी में मौजूद मौजूदा उपयोगकर्ता के टाइप की जानकारी देने के लिए, SideEffect का इस्तेमाल करके उसकी वैल्यू अपडेट करें.

@Composable
fun rememberFirebaseAnalytics(user: User): FirebaseAnalytics {
    val analytics: FirebaseAnalytics = remember {
        FirebaseAnalytics()
    }

    // On every successful composition, update FirebaseAnalytics with
    // the userType from the current User, ensuring that future analytics
    // events have this metadata attached
    SideEffect {
        analytics.setUserProperty("userType", user.userType)
    }
    return analytics
}

ज़्यादा जानकारी के लिए, Compose में साइड-इफ़ेक्ट देखें.

सिस्टम को सच्चाई के स्रोत के रूप में देखें

अगर View सिस्टम के पास स्टेट का मालिकाना हक है और वह इसे Compose के साथ शेयर करता है, तो हमारा सुझाव है कि आप स्टेट को mutableStateOf ऑब्जेक्ट में रैप करें, ताकि इसे Compose के लिए थ्रेड-सेफ़ बनाया जा सके. इस तरीके का इस्तेमाल करने पर, कंपोज़ेबल फ़ंक्शन आसान हो जाते हैं, क्योंकि उनमें सच्चाई का सोर्स नहीं होता. हालांकि, व्यू सिस्टम को म्यूट किए जा सकने वाली स्थिति और उस स्टेट का इस्तेमाल करने वाले व्यू को अपडेट करना होता है.

इस उदाहरण में, CustomViewGroup में एक TextView और एक ComposeView शामिल है, जिसके अंदर TextField कंपोज़ेबल है. TextView में, TextField में उपयोगकर्ता के टाइप किए गए कॉन्टेंट को दिखाना ज़रूरी है.

class CustomViewGroup @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0
) : LinearLayout(context, attrs, defStyle) {

    // Source of truth in the View system as mutableStateOf
    // to make it thread-safe for Compose
    private var text by mutableStateOf("")

    private val textView: TextView

    init {
        orientation = VERTICAL

        textView = TextView(context)
        val composeView = ComposeView(context).apply {
            setContent {
                MaterialTheme {
                    TextField(value = text, onValueChange = { updateState(it) })
                }
            }
        }

        addView(textView)
        addView(composeView)
    }

    // Update both the source of truth and the TextView
    private fun updateState(newValue: String) {
        text = newValue
        textView.text = newValue
    }
}

शेयर किए गए यूज़र इंटरफ़ेस (यूआई) को माइग्रेट करना

अगर आपको धीरे-धीरे लिखें पर माइग्रेट करना है, तो हो सकता है कि आपको लिखें और व्यू सिस्टम, दोनों में शेयर किए गए यूज़र इंटरफ़ेस (यूआई) एलिमेंट इस्तेमाल करने पड़ें. उदाहरण के लिए, अगर आपके ऐप्लिकेशन में कोई कस्टम CallToActionButton कॉम्पोनेंट है, तो आपको उसे Compose और व्यू-आधारित, दोनों स्क्रीन में इस्तेमाल करना पड़ सकता है.

Compose में, शेयर किए गए यूज़र इंटरफ़ेस (यूआई) एलिमेंट, कॉम्पोज़ेबल बन जाते हैं. इनका इस्तेमाल पूरे ऐप्लिकेशन में फिर से किया जा सकता है. भले ही, एलिमेंट को एक्सएमएल का इस्तेमाल करके स्टाइल किया गया हो या वह कस्टम व्यू हो. उदाहरण के लिए, आपको अपने कस्टम कॉल-टू-ऐक्शन Button कॉम्पोनेंट के लिए, CallToActionButton कॉम्पोज़ेबल बनाना होगा.

व्यू पर आधारित स्क्रीन में कॉम्पोज़ेबल का इस्तेमाल करने के लिए, AbstractComposeView से बड़ा कस्टम व्यू रैपर बनाएं. इसके ओवरराइड किए गए Content कंपोज़ेबल में, अपने बनाए गए कंपोज़ेबल को अपनी कंपोज़ थीम में रैप करें, जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है:

@Composable
fun CallToActionButton(
    text: String,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
) {
    Button(
        colors = ButtonDefaults.buttonColors(
            containerColor = MaterialTheme.colorScheme.secondary
        ),
        onClick = onClick,
        modifier = modifier,
    ) {
        Text(text)
    }
}

class CallToActionViewButton @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0
) : AbstractComposeView(context, attrs, defStyle) {

    var text by mutableStateOf("")
    var onClick by mutableStateOf({})

    @Composable
    override fun Content() {
        YourAppTheme {
            CallToActionButton(text, onClick)
        }
    }
}

ध्यान दें कि कंपोज़ेबल पैरामीटर, कस्टम व्यू में बदले जा सकने वाले वैरिएबल बन जाते हैं. इससे कस्टम CallToActionViewButton व्यू, किसी पारंपरिक व्यू की तरह इनफ़्लेटेबल और इस्तेमाल करने लायक बन जाता है. नीचे व्यू बाइंडिंग के साथ इसका एक उदाहरण देखें:

class ViewBindingActivity : ComponentActivity() {

    private lateinit var binding: ActivityExampleBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityExampleBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.callToAction.apply {
            text = getString(R.string.greeting)
            onClick = { /* Do something */ }
        }
    }
}

अगर कस्टम कॉम्पोनेंट में बदलाव की सुविधा वाली स्थिति है, तो सही स्थिति का सोर्स देखें.

प्रज़ेंटेशन से अलग होने की प्रोसेस को प्राथमिकता दें

आम तौर पर, View स्टेटफ़ुल होता है. View, उन फ़ील्ड को मैनेज करता है जिनमें यह बताया जाता है कि क्या दिखाना है और कैसे दिखाना है. जब View को कंपोज़ में बदला जाता है, तब रेंडर हो रहे डेटा को अलग-अलग करने की कोशिश करें, ताकि एकतरफ़ा डेटा फ़्लो मिल सके. इस बारे में ज़्यादा जानने के लिए, स्टेट लिफ़्टिंग में जाएं.

उदाहरण के लिए, View में visibility प्रॉपर्टी होती है, जिससे यह पता चलता है कि प्रॉपर्टी दिख रही है, नहीं दिख रही है या मौजूद नहीं है. यह View की एक खास प्रॉपर्टी है. कोड के अन्य हिस्सों से View के दिखने की सेटिंग में बदलाव हो सकता है. हालांकि, View को दिखने की मौजूदा सेटिंग के बारे में सिर्फ़ View को पता होता है. View के दिखने की सेटिंग में गड़बड़ी हो सकती है. यह सेटिंग अक्सर View से जुड़ी होती है.

इसके उलट, Compose की मदद से Kotlin में कंडिशनल लॉजिक का इस्तेमाल करके, अलग-अलग कंपोज़ेबल को आसानी से दिखाया जा सकता है:

@Composable
fun MyComposable(showCautionIcon: Boolean) {
    if (showCautionIcon) {
        CautionIcon(/* ... */)
    }
}

डिज़ाइन के हिसाब से, CautionIcon को यह जानने या ध्यान रखने की ज़रूरत नहीं है कि उसे क्यों दिखाया जा रहा है. साथ ही, visibility का कोई कॉन्सेप्ट नहीं है: यह कॉम्पोज़िशन में है या नहीं.

स्टेटस मैनेजमेंट और प्रज़ेंटेशन लॉजिक को अलग-अलग करके, यूज़र इंटरफ़ेस (यूआई) में स्टेटस के कन्वर्ज़न के तौर पर कॉन्टेंट को दिखाने के तरीके को ज़्यादा आसानी से बदला जा सकता है. ज़रूरत पड़ने पर, कंपोज़ेबल को ऊंची स्थिति में रखने से, कंपोज़ेबल को फिर से इस्तेमाल किया जा सकता है. ऐसा इसलिए, क्योंकि राज्य के मालिकाना हक के लिए अलग-अलग विकल्प मिलते हैं.

कैप्सल किए गए और फिर से इस्तेमाल किए जा सकने वाले कॉम्पोनेंट का प्रमोशन करना

View एलिमेंट में अक्सर यह जानकारी मौजूद होती है कि वे कहां रहते हैं: Activity, Dialog, Fragment या View की किसी अन्य हैरारकी में. इनमें अक्सर स्टैटिक लेआउट फ़ाइलों से इनफ़्लेट किया जाता है, इसलिए View का पूरा स्ट्रक्चर बहुत कठोर होता है. इससे, कूपलिंग ज़्यादा टाइट हो जाती है और View को बदलना या फिर से इस्तेमाल करना मुश्किल हो जाता है.

उदाहरण के लिए, कस्टम View यह मान सकता है कि उसमें किसी खास आईडी वाले किसी खास टाइप का चाइल्ड व्यू है और कोई कार्रवाई होने पर सीधे अपनी प्रॉपर्टी बदल सकता है. इससे इन View एलिमेंट को एक साथ जोड़ा जा सकता है: बच्चे को न ढूंढने पर, पसंद के मुताबिक बनाया गया View क्रैश हो सकता है या काम करना बंद कर सकता है. साथ ही, ऐसा हो सकता है कि पसंद के मुताबिक बनाए गए View पैरंट के बिना, बच्चा फिर से इस्तेमाल न कर पाए.

Compose में, फिर से इस्तेमाल किए जा सकने वाले कॉम्पोज़ेबल का इस्तेमाल करने पर, यह समस्या कम होती है. माता-पिता, आसानी से स्थिति और कॉलबैक तय कर सकते हैं. इससे, आपको यह जानने की ज़रूरत नहीं पड़ती कि इस्तेमाल किए जाने वाले कॉम्पोज़ेबल कहां इस्तेमाल किए जाएंगे.

@Composable
fun AScreen() {
    var isEnabled by rememberSaveable { mutableStateOf(false) }

    Column {
        ImageWithEnabledOverlay(isEnabled)
        ControlPanelWithToggle(
            isEnabled = isEnabled,
            onEnabledChanged = { isEnabled = it }
        )
    }
}

ऊपर दिए गए उदाहरण में, तीनों हिस्से ज़्यादा कंटेनप्लेट किए गए हैं और कम कपल्ड हैं:

  • ImageWithEnabledOverlay को सिर्फ़ यह जानने की ज़रूरत है कि मौजूदा isEnabled स्थिति क्या है. इसके लिए यह जानने की ज़रूरत नहीं है कि ControlPanelWithToggle मौजूद है या यह कैसे कंट्रोल किया जा सकता है.

  • ControlPanelWithToggle को यह नहीं पता कि ImageWithEnabledOverlay मौजूद है. isEnabled को दिखाने के लिए, शून्य, एक या उससे ज़्यादा तरीके हो सकते हैं. साथ ही, ControlPanelWithToggle में कोई बदलाव नहीं करना पड़ेगा.

  • माता-पिता के लिए, इस बात से कोई फ़र्क़ नहीं पड़ता कि ImageWithEnabledOverlay या ControlPanelWithToggle कितना नेस्ट किया गया है. ये बच्चे, बदलावों को ऐनिमेशन के तौर पर दिखा सकते हैं, कॉन्टेंट को बदल सकते हैं या कॉन्टेंट को दूसरे बच्चों को भेज सकते हैं.

इस पैटर्न को कंट्रोल का इनवर्ज़न कहा जाता है. इस बारे में ज़्यादा जानने के लिए, CompositionLocal दस्तावेज़ पढ़ें.

स्क्रीन के साइज़ में होने वाले बदलावों को मैनेज करना

रिस्पॉन्सिव View लेआउट बनाने के मुख्य तरीकों में से एक यह है कि आपके पास अलग-अलग विंडो साइज़ के लिए अलग-अलग संसाधन हों. स्क्रीन-लेवल के लेआउट से जुड़े फ़ैसले लेने के लिए, क्वालिफ़ाइड रिसॉर्स अब भी एक विकल्प हैं. हालांकि, कंडिशनल लॉजिक के ज़रिए, कोड में लेआउट को पूरी तरह से बदलना आसान हो जाता है. ज़्यादा जानने के लिए, विंडो साइज़ क्लास का इस्तेमाल करना लेख पढ़ें.

इसके अलावा, Compose में अडैप्टिव यूज़र इंटरफ़ेस बनाने के लिए उपलब्ध तकनीकों के बारे में जानने के लिए, अलग-अलग स्क्रीन साइज़ के साथ काम करना देखें.

व्यू की मदद से नेस्ट किया गया स्क्रोलिंग

नेस्ट किए गए व्यू एलिमेंट और नेस्ट किए गए कॉम्पोज़ेबल के बीच नेस्ट की गई स्क्रोलिंग इंटरऑपरेबिलिटी को चालू करने के तरीके के बारे में ज़्यादा जानने के लिए, नेस्ट की गई स्क्रोलिंग इंटरऑपरेबिलिटी लेख पढ़ें.

RecyclerView में ईमेल लिखना

RecyclerView के 1.3.0-alpha02 वर्शन से, RecyclerView में कॉम्पोज़ेबल बेहतर परफ़ॉर्म कर रहे हैं. उन फ़ायदों को देखने के लिए, पक्का करें कि आपके पास RecyclerView के कम से कम 1.3.0-alpha02 वर्शन हो.

WindowInsets व्यू के साथ इंटरऑप

अगर आपकी स्क्रीन पर व्यू और कंपोज़ कोड, दोनों एक ही क्रम में हैं, तो आपको डिफ़ॉल्ट इनसेट को बदलना पड़ सकता है. इस मामले में, आपको यह साफ़ तौर पर बताना होगा कि कौनसे इनसेट का इस्तेमाल करना चाहिए और किन्हें अनदेखा करना चाहिए.

उदाहरण के लिए, अगर आपका सबसे बाहरी लेआउट Android View का लेआउट है, तो आपको व्यू सिस्टम में इनसेट का इस्तेमाल करना चाहिए. साथ ही, इन्हें Compose के लिए अनदेखा कर देना चाहिए. इसके अलावा, अगर आपका सबसे बाहरी लेआउट कोई कॉम्पोज़ेबल है, तो आपको Compose में इनसेट का इस्तेमाल करना चाहिए. साथ ही, AndroidView कॉम्पोज़ेबल को उसी हिसाब से पैड करना चाहिए.

डिफ़ॉल्ट रूप से, हर ComposeView खपत के WindowInsetsCompat लेवल पर सभी इनसेट का इस्तेमाल करता है. इस डिफ़ॉल्ट तरीके को बदलने के लिए, ComposeView.consumeWindowInsets को false पर सेट करें.

ज़्यादा जानकारी के लिए, लिखें में WindowInsets दस्तावेज़ पढ़ें.