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

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

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

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

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

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

Compose ऐप्लिकेशन के लिए, Material के दो वर्शन उपलब्ध हैं:

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

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

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

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

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

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

कंपोज़/व्यू के मिले-जुले यूज़र इंटरफ़ेस (यूआई) की जांच करना

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

जब किसी गतिविधि या फ़्रैगमेंट में Compose का इस्तेमाल किया जाता है, तब आपको ActivityScenarioRule के बजाय createAndroidComposeRule का इस्तेमाल करना होगा. createAndroidComposeRuleActivityScenarioRule, 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()
    }
}

टेस्टिंग के बारे में ज़्यादा जानने के लिए, कंपोज़ लेआउट की टेस्टिंग करना लेख पढ़ें. यूआई टेस्टिंग फ़्रेमवर्क के साथ काम करने के लिए, Espresso के साथ काम करने की सुविधा और UiAutomator के साथ काम करने की सुविधा देखें.

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

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

ईमेल लिखते समय ViewModel का इस्तेमाल करना

अगर Architecture Components 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") ?: "")
        }
    }
}

स्टेट सोर्स ऑफ़ ट्रुथ

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

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

सही और पूरी जानकारी के सोर्स के तौर पर जवाब लिखो

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

उदाहरण के लिए, आपकी Analytics लाइब्रेरी, उपयोगकर्ताओं को सेगमेंट में बांटने की सुविधा दे सकती है. इसके लिए, वह सभी 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 में साइड इफ़ेक्ट लेख पढ़ें.

सिस्टम को भरोसेमंद सोर्स के तौर पर देखना

अगर व्यू सिस्टम के पास स्टेट का मालिकाना हक है और वह इसे 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
    }
}

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

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

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

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

@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 को Compose में बदलते समय, रेंडर किए जा रहे डेटा को अलग करें. इससे एकतरफ़ा डेटा फ़्लो हासिल किया जा सकता है. इसके बारे में स्टेट होइस्टिंग में ज़्यादा बताया गया है.

उदाहरण के लिए, View में visibility प्रॉपर्टी होती है. यह प्रॉपर्टी बताती है कि दिख रहा है, नहीं दिख रहा है या हट गया है. यह 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 की मदद से, सामान्य शर्तों के आधार पर कोड में लेआउट को पूरी तरह से बदलना बहुत आसान हो जाता है. ज़्यादा जानने के लिए, विंडो के साइज़ के हिसाब से क्लास इस्तेमाल करना लेख पढ़ें.

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

व्यू के साथ नेस्टेड स्क्रोलिंग

स्क्रोल किए जा सकने वाले View एलिमेंट और स्क्रोल किए जा सकने वाले कंपोज़ेबल के बीच, नेस्टेड स्क्रोलिंग इंटरऑप को दोनों दिशाओं में चालू करने के बारे में ज़्यादा जानने के लिए, नेस्टेड स्क्रोलिंग इंटरऑप पढ़ें.

RecyclerView में लिखें

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

WindowInsets Views के साथ इंटरऑप

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

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

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

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