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

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

पढ़ने में लगने वाला समय: 6 मिनट
मेघन मेहता की प्रोफ़ाइल देखें
Meghan Mehta डेवलपर एडवोकेट, Android

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

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

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

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

टेस्ट में कोरूटीन को लागू करना

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

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

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

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

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

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


@PreviewWrapper(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 पर अपग्रेड कर दिया जाएगा. इसमें एजीपी 9 और Compose पर निर्भर सभी ऐप्लिकेशन और लाइब्रेरी शामिल होंगी. हमारा सुझाव है कि आप रिलीज़ किए गए नए रिलीज़ के लिए तैयार वर्शन के साथ अप-टू-डेट रहें. ऐसा इसलिए, क्योंकि Compose का मकसद नए compileSdks को तुरंत अपनाना है, ताकि Android की नई सुविधाओं का ऐक्सेस दिया जा सके. यहां दिए गए दस्तावेज़ को ज़रूर देखें. इसमें आपको इस बारे में ज़्यादा जानकारी मिलेगी कि अलग-अलग एपीआई लेवल के लिए, एजीपी का कौनसा वर्शन काम करता है. 

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 (एक्सपेरिमेंट के तौर पर उपलब्ध)

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 रनटाइम इसका इस्तेमाल, कंपोज़िशन की हैरारकी की स्थिति को ट्रैक करने, अमान्य होने/फिर से कंपोज़ करने की प्रोसेस को ट्रैक करने, याद रखी गई वैल्यू को सेव करने, और रनटाइम के दौरान कंपोज़िशन के सभी मेटाडेटा को ट्रैक करने के लिए करता है. इस नए तरीके को परफ़ॉर्मेंस को बेहतर बनाने के लिए डिज़ाइन किया गया है. खास तौर पर, रैंडम बदलावों के लिए.

SlotTable की नई सुविधा आज़माने के लिए, ComposeRuntimeFlags.isLinkBufferComposerEnabled को चालू करें. 

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

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

लेखक:
पढ़ना जारी रखें