प्रॉडक्ट से जुड़ी खबरें

Jetpack Compose की अप्रैल '26 की रिलीज़ में नया क्या है

पांच मिनट में पढ़ें
Meghan Mehta
डेवलपर एडवोकेट, Android

आज, Jetpack Compose का 26 अप्रैल वाला वर्शन स्टेबल है. इस रिलीज़ में, कोर कंपोज़ मॉड्यूल का वर्शन 1.11 शामिल है. पूरी BOM मैपिंग देखें. इसमें शेयर किए गए एलिमेंट को डीबग करने वाले टूल, ट्रैकपैड इवेंट वगैरह भी शामिल हैं. हमारे पास कुछ एक्सपेरिमेंटल एपीआई भी हैं. हम चाहते हैं कि आप उन्हें आज़माएं और हमें उनके बारे में सुझाव/राय दें या शिकायत करें.

आज रिलीज़ हुए वर्शन का इस्तेमाल करने के लिए, अपने Compose BOM वर्शन को इस पर अपग्रेड करें:

implementation(platform("androidx.compose:compose-bom:2026.04.01"))

Compose 1.11.0 में हुए बदलाव

जांच में कोरुटीन का इस्तेमाल करना

हम कंपोज़ के टेस्ट के समय को मैनेज करने के तरीके में एक बड़ा अपडेट कर रहे हैं. Compose 1.10 में, ऑप्ट-इन करने की अवधि के बारे में बताया गया था. अब v2 टेस्टिंग एपीआई डिफ़ॉल्ट रूप से उपलब्ध हैं और v1 एपीआई बंद कर दिए गए हैं. मुख्य बदलाव यह है कि डिफ़ॉल्ट टेस्ट डिस्पैचर बदल गया है. v1 API, UnconfinedTestDispatcher पर निर्भर करते थे. यह को-रूटीन को तुरंत एक्ज़ीक्यूट करता था. वहीं, v2 API, StandardTestDispatcher का इस्तेमाल करते हैं. इसका मतलब है कि आपकी जांचों में जब कोई को-रूटीन लॉन्च किया जाता है, तो उसे अब कतार में रखा जाता है. साथ ही, वर्चुअल क्लॉक के आगे बढ़ने तक उसे लागू नहीं किया जाता.

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

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

शेयर किए गए एलिमेंट में सुधार और ऐनिमेशन टूलिंग

हमने शेयर किए गए एलिमेंट और Modifier.animatedBounds के लिए, कुछ काम के विज़ुअल डीबगिंग टूल भी जोड़े हैं. अब आपको यह पता चल सकता है कि पर्दे के पीछे क्या हो रहा है. जैसे, टारगेट बाउंड्री, ऐनिमेशन ट्रैजेक्ट्री, और कितने मैच मिले. इससे यह पता लगाना आसान हो जाता है कि ट्रांज़िशन आपकी उम्मीद के मुताबिक क्यों काम नहीं कर रहा है. नई टूलिंग का इस्तेमाल करने के लिए, बस अपने SharedTransitionLayout को LookaheadAnimationVisualDebugging कंपोज़ेबल से रैप करें. 

LookaheadAnimationVisualDebugging(
    overlayColor = Color(0x4AE91E63),
    isEnabled = true,
    multipleMatchesColor = Color.Green,
    isShowKeylabelEnabled = false,
    unmatchedElementColor = Color.Red,
) {
    SharedTransitionLayout {
        CompositionLocalProvider(
            LocalSharedTransitionScope provides this,
        ) {
            // your content
        }
    }
}

ट्रैकपैड इवेंट

हमने ट्रैकपैड के लिए, Compose की सुविधा को बेहतर बनाया है. जैसे, लैपटॉप में पहले से मौजूद ट्रैकपैड, टैबलेट से अटैच किए जा सकने वाले ट्रैकपैड या बाहरी/वर्चुअल ट्रैकपैड. अब आम तौर पर, बेसिक ट्रैकपैड इवेंट को PointerType.Mouse इवेंट माना जाएगा. इससे माउस और ट्रैकपैड के व्यवहार को एक जैसा बनाया जा सकेगा, ताकि उपयोगकर्ता की उम्मीदों को बेहतर तरीके से पूरा किया जा सके. पहले, इन ट्रैकपैड इवेंट को PointerType.Touch की नकली टचस्क्रीन उंगलियों के तौर पर माना जाता था. इससे उपयोगकर्ताओं को भ्रम होता था. उदाहरण के लिए, ट्रैकपैड पर क्लिक करके खींचने और छोड़ने से, टेक्स्ट चुनने के बजाय स्क्रोल होगा. Compose की नई रिलीज़ में, इन इवेंट के लिए पॉइंटर टाइप बदल दिया गया है. इसलिए, अब ट्रैकपैड से क्लिक और ड्रैग करने पर स्क्रोल नहीं होगा.

हमने एपीआई 34 के बाद से, प्लैटफ़ॉर्म पर पहचाने जाने वाले ज़्यादा मुश्किल ट्रैकपैड जेस्चर के लिए भी सहायता जोड़ी है. इनमें दो उंगलियों से स्वाइप करना और पिंच करना शामिल है. इन जेस्चर को Modifier.scrollable और Modifier.transformable जैसे कॉम्पोनेंट अपने-आप पहचान लेते हैं, ताकि ट्रैकपैड के साथ बेहतर तरीके से काम किया जा सके.

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

ट्रैकपैड के व्यवहार की जांच करने के लिए, performTrackpadInput, के साथ नए टेस्टिंग एपीआई उपलब्ध हैं. इनकी मदद से, ट्रैकपैड का इस्तेमाल करते समय अपने ऐप्लिकेशन के व्यवहार की पुष्टि की जा सकती है. अगर आपके पास कस्टम जेस्चर डिटेक्टर हैं, तो इनपुट टाइप के हिसाब से उनके व्यवहार की पुष्टि करें. जैसे, टचस्क्रीन, माउस, ट्रैकपैड, और स्टाइलस. साथ ही, यह पक्का करें कि माउस के स्क्रोल व्हील और ट्रैकपैड के जेस्चर काम करते हों.

beforeAndAfter.webp

कंपोज़िशन होस्ट की डिफ़ॉल्ट सेटिंग (Compose runtime)

हमने HostDefaultProvider, LocalHostDefaultProvider, HostDefaultKey, और ViewTreeHostDefaultKey को पेश किया है, ताकि होस्ट-लेवल की सेवाओं को सीधे तौर पर compose-runtime के ज़रिए उपलब्ध कराया जा सके. इससे लाइब्रेरी को लुकअप के लिए, compose-ui पर निर्भर नहीं रहना पड़ता. साथ ही, Kotlin Multiplatform को बेहतर तरीके से सपोर्ट किया जा सकता है. इन वैल्यू को कंपोज़िशन ट्री से लिंक करने के लिए, लाइब्रेरी के लेखक compositionLocalWithHostDefaultOf का इस्तेमाल करके CompositionLocal बना सकते हैं. इससे होस्ट से डिफ़ॉल्ट वैल्यू मिलती हैं.

रैपर की झलक देखना

Android Studio में कस्टम प्रीव्यू एक नई सुविधा है. इसकी मदद से, यह तय किया जा सकता है कि Compose प्रीव्यू का कॉन्टेंट कैसे दिखाया जाए.

PreviewWrapperProvider इंटरफ़ेस लागू करके और नया @PreviewWrapper एनोटेशन लागू करके, कस्टम लॉजिक को आसानी से इंजेक्ट किया जा सकता है. जैसे, कोई खास Theme लागू करना. इस एनोटेशन को @Composable और @Preview या @MultiPreview के साथ एनोटेट किए गए फ़ंक्शन पर लागू किया जा सकता है. इससे एक सामान्य और इस्तेमाल में आसान समाधान मिलता है. यह समाधान, झलक वाली सुविधाओं के साथ काम करता है और बार-बार इस्तेमाल होने वाले कोड को काफ़ी हद तक कम करता है.

class ThemeWrapper: PreviewWrapper {
    @Composable
    override fun Wrap(content: @Composable (() -> Unit)) {
        JetsnackTheme {
            content()
        }
    }
}

@PreviewWrapperProvider(ThemeWrapper::class)
@Preview
@Composable
private fun ButtonPreview() {
    // JetsnackTheme in effect
    Button(onClick = {}) {
        Text(text = "Demo")
    }
}

बंद की गई और हटाई गई सुविधाएं

  • Compose 1.10 की ब्लॉग पोस्ट में बताए गए तरीके के मुताबिक, हम Modifier.onFirstVisible() को बंद कर रहे हैं. इसके नाम की वजह से अक्सर गलतफ़हमियां होती थीं. खास तौर पर, लेज़ी लेआउट में ऐसा होता था, जहां स्क्रोल करने के दौरान यह कई बार ट्रिगर होता था. हमारा सुझाव है कि आप Modifier.onVisibilityChanged() पर माइग्रेट करें. इससे, इस्तेमाल के खास उदाहरण की ज़रूरतों के हिसाब से, दिखने की स्थितियों को मैन्युअल तरीके से ज़्यादा सटीक तरीके से ट्रैक किया जा सकता है.
  • ComposeFoundationFlags.isTextFieldDpadNavigationEnabled फ़्लैग को हटा दिया गया है, क्योंकि अब TextFields के लिए डी-पैड नेविगेशन की सुविधा डिफ़ॉल्ट रूप से हमेशा चालू रहती है. नए वर्शन में, यह पक्का किया जाता है कि गेमपैड या टीवी रिमोट से मिले डी-पैड इवेंट, सबसे पहले कर्सर को दी गई दिशा में ले जाएं. कर्सर के टेक्स्ट के आखिर में पहुंचने के बाद ही, फ़ोकस को किसी दूसरे एलिमेंट पर ले जाया जा सकता है.

आने वाले एपीआई

Compose 1.12.0 की आने वाली रिलीज़ में, compileSdk को compileSdk 37 में अपग्रेड किया जाएगा. साथ ही, AGP 9 और Compose पर निर्भर रहने वाले सभी ऐप्लिकेशन और लाइब्रेरी को यह ज़रूरी शर्त पूरी करनी होगी. हमारा सुझाव है कि आप रिलीज़ किए गए नए वर्शन के बारे में अप-टू-डेट रहें. ऐसा इसलिए, क्योंकि Compose का मकसद नई compileSdks को तुरंत अपनाना है, ताकि Android की नई सुविधाओं का ऐक्सेस दिया जा सके. अलग-अलग एपीआई लेवल के लिए, AGP के किस वर्शन का इस्तेमाल किया जा सकता है, इस बारे में ज़्यादा जानने के लिए, यहां दिया गया दस्तावेज़ ज़रूर देखें. 

Compose 1.11.0 में, इन एपीआई को @Experimental के तौर पर पेश किया गया है. हम चाहते हैं कि आप इन्हें अपने ऐप्लिकेशन में आज़माएं और हमें अपना सुझाव/राय दें या शिकायत करें. ध्यान दें कि @Experimental APIs को शुरुआती तौर पर जांच करने और सुझाव/राय देने के लिए उपलब्ध कराया जाता है. आने वाले समय में, इनमें बड़े बदलाव किए जा सकते हैं या इन्हें हटाया जा सकता है.

स्टाइल (एक्सपेरिमेंट के तौर पर उपलब्ध)

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

दबाए गए बटन के बैकग्राउंड की स्टाइल को बदलने का सामान्य उदाहरण:

@Composable
fun LoginButton(modifier: Modifier = Modifier) {
    Button(
        onClick = {
            // Login logic
        },
        modifier = modifier,
        style = {
            background(
                Brush.linearGradient(
                    listOf(lightPurple, lightBlue)
                )
            )
            width(75.dp)
            height(50.dp)
            textAlign(TextAlign.Center)
            externalPadding(16.dp)

            pressed {
                background(
                    Brush.linearGradient(
                        listOf(Color.Magenta, Color.Red)
                    )
                )
            }
        }
    ){
        Text(
            text = "Login",
        )
    }
}
styles.webp

दस्तावेज़ देखें और किसी भी गड़बड़ी की शिकायत यहां करें.

MediaQuery (एक्सपेरिमेंट के तौर पर उपलब्ध)

नए mediaQuery एपीआई की मदद से, यूज़र इंटरफ़ेस (यूआई) को उसके एनवायरमेंट के हिसाब से अडजस्ट किया जा सकता है. यह एपीआई, यूज़र इंटरफ़ेस (यूआई) को अडजस्ट करने का एक बेहतर तरीका है. यह UiMediaScope में जटिल जानकारी को आसान शर्तों में बदल देता है. इससे यह पक्का होता है कि कॉन्टेंट को सिर्फ़ तब फिर से कंपोज़ किया जाए, जब इसकी ज़रूरत हो.

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

@Composable
fun isTabletopPosture(
    context: Context = LocalContext.current
): Boolean {
    val windowLayoutInfo by
        WindowInfoTracker
            .getOrCreate(context)
            .windowLayoutInfo(context)
            .collectAsStateWithLifecycle(null)

    return windowLayoutInfo.displayFeatures.any { displayFeature ->
        displayFeature is FoldingFeature &&
            displayFeature.state == FoldingFeature.State.HALF_OPENED &&
            displayFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
    }
}

@Composable
fun VideoPlayer() {
    if(isTabletopPosture()) {
        TabletopLayout()
    } else {
        FlatLayout()
    }
}

अब UIMediaQuery की मदद से, डिवाइस की प्रॉपर्टी के बारे में क्वेरी करने के लिए, mediaQuery सिंटैक्स जोड़ा जा सकता है. जैसे, अगर कोई डिवाइस टेबलटॉप मोड में है, तो:

@OptIn(ExperimentalMediaQueryApi::class)
@Composable
fun VideoPlayer() {
    if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) {
        TabletopLayout()
    } else {
        FlatLayout()
    }
}

दस्तावेज़ देखें और किसी भी गड़बड़ी की शिकायत यहां करें.

ग्रिड (एक्सपेरिमेंट के तौर पर उपलब्ध)

Grid, Jetpack Compose में जटिल और दो डाइमेंशन वाले लेआउट बनाने के लिए एक नया और बेहतरीन एपीआई है. Row और Column, लीनियर डिज़ाइन के लिए बेहतरीन हैं. वहीं, Grid की मदद से, आपको स्क्रीन-लेवल के आर्किटेक्चर और जटिल कॉम्पोनेंट पर स्ट्रक्चरल कंट्रोल मिलता है. इसके लिए, आपको स्क्रोल की जा सकने वाली सूची का इस्तेमाल करने की ज़रूरत नहीं होती. Grid की मदद से, ट्रैक, गैप, और सेल का इस्तेमाल करके लेआउट तय किया जा सकता है. इसमें साइज़ के लिए, Dp, प्रतिशत, कॉन्टेंट के इंट्रिंसिक साइज़, और फ़्लेक्सिबल "Fr" यूनिट जैसे विकल्प मिलते हैं. 

@OptIn(ExperimentalGridApi::class)
@Composable
fun GridExample() {
    Grid(
        config = {
            repeat(4) { column(0.25f) }
            repeat(2) { row(0.5f) }
            gap(16.dp)
        }
    ) {
        Card1(modifier = Modifier.gridItem(rowSpan = 2)
        Card2(modifier = Modifier.gridItem(colmnSpan = 3)
        Card3(modifier = Modifier.gridItem(columnSpan = 2)
        Card4()
    }
}

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

Grid.gif

दस्तावेज़ देखें और किसी भी गड़बड़ी की शिकायत यहां करें. 

FlexBox (Experimental)

FlexBox एक लेआउट कंटेनर है. इसे बेहतर परफ़ॉर्मेंस और अडैप्टिव यूज़र इंटरफ़ेस (यूआई) के लिए डिज़ाइन किया गया है. यह उपलब्ध कंटेनर डाइमेंशन के आधार पर, आइटम के साइज़ और स्पेस डिस्ट्रिब्यूशन को मैनेज करता है.  यह रैपिंग (wrap) और आइटम के मल्टी-ऐक्सिस अलाइनमेंट (justifyContent, alignItems, alignContent) जैसे मुश्किल टास्क को हैंडल करता है. इससे आइटम को कंटेनर में फ़िट करने के लिए, बड़ा (grow) या छोटा (shrink) किया जा सकता है. 

@OptIn(ExperimentalFlexBoxApi::class)
fun FlexBoxWrapping(){
    FlexBox(
        config = {
            wrap(FlexWrap.Wrap)
            gap(8.dp)
        }
    ) {
        RedRoundedBox()
        BlueRoundedBox()
        GreenRoundedBox(modifier = Modifier.width(350.dp).flex { grow(1.0f) })
        OrangeRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.7f) })
        PinkRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.3f) })
    }
}
AnimationGif.gif

दस्तावेज़ देखें और किसी भी गड़बड़ी की शिकायत यहां करें.

SlotTable को लागू करने का नया तरीका (एक्सपेरिमेंट के तौर पर उपलब्ध)

हमने SlotTable को लागू करने का एक नया तरीका पेश किया है. यह इस रिलीज़ में डिफ़ॉल्ट रूप से बंद होता है. SlotTable एक इंटरनल डेटा स्ट्रक्चर है. इसका इस्तेमाल Compose runtime, कंपोज़िशन हाइरार्की की स्थिति को ट्रैक करने, अमान्यताओं/रीकंपोज़िशन को ट्रैक करने, याद रखी गई वैल्यू को सेव करने, और रनटाइम पर कंपोज़िशन के सभी मेटाडेटा को ट्रैक करने के लिए करता है. इस नए बदलाव को परफ़ॉर्मेंस को बेहतर बनाने के लिए डिज़ाइन किया गया है. खास तौर पर, रैंडम बदलावों के लिए.

SlotTable को आज़माने के लिए, ComposeRuntimeFlags.isLinkBufferComposerEnabled को चालू करें. 

आज ही कोडिंग शुरू करें!

Jetpack Compose में कई नए और शानदार एपीआई उपलब्ध हैं. साथ ही, आने वाले समय में और भी एपीआई उपलब्ध होंगे. इसलिए, Jetpack Compose पर माइग्रेट करने का यह सबसे सही समय है.  हमेशा की तरह, हम आपके सुझाव, शिकायत या राय और सुविधाओं के अनुरोधों को अहमियत देते हैं. खास तौर पर, @Experimental सुविधाओं के बारे में सुझाव, शिकायत या राय और अनुरोधों को. कृपया इन्हें यहां सबमिट करें. म्यूज़िक बनाने का आनंद लें!

इसे लिखा है:

पढ़ना जारी रखें