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

Jetpack Compose के अप्रैल '26 वर्शन में नया क्या है

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

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

आज के वर्शन का इस्तेमाल करने के लिए, अपने 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 रनटाइम)

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

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

स्टाइल (प्रयोग के तौर पर उपलब्ध)

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

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

@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 (प्रयोग के तौर पर उपलब्ध)

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 सुविधाओं के बारे में. कृपया इन्हें यहां सबमिट करें. कंपोज़िंग के लिए शुभकामनाएं!

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