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

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

पढ़ने में 5 मिनट लगेंगे
निक बुचर की प्रोफ़ाइल देखें
Nick Butcher प्रॉडक्ट मैनेजर

आज, Jetpack Compose की अगस्त 2026 वाली रिलीज़ का स्टेबल वर्शन उपलब्ध है! इस रिलीज़ में, Compose के मुख्य मॉड्यूल के लिए वर्शन 1.12 उपलब्ध है. पूरी BOM मैपिंग देखें. इसमें कई विज़ुअल एपीआई शामिल हैं. जैसे, मेश ग्रेडिएंट और वाइड कलर गैमट (डब्ल्यूसीजी) के लिए सहायता. साथ ही, स्ट्रक्चरल लेआउट की सुविधाएं भी शामिल हैं. जैसे, Grid में नाम वाली जगहें, Android के क्रेडेंशियल मैनेजर के साथ आसानी से इंटिग्रेट करना, और टेस्टिंग और परफ़ॉर्मेंस में काफ़ी सुधार करना.

अपने प्रोजेक्ट को आज की रिलीज़ के हिसाब से अपडेट करने के लिए, Compose BOM के वर्शन को 2026.08.00 पर अपग्रेड करें:

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

नुकसान पहुंचा सकने वाले बदलाव

  • AGP और कंपाइल SDK: कंपोज़ 1.12 कंपाइल SDK को API 37 में अपडेट करता है, जिसके लिए न्यूनतम AGP 9.1.2 की आवश्यकता होती है. याद दिला दें कि Compose हमेशा नवीनतम compileSdk को ही लक्षित करेगा. इस बदलाव के बारे में और ज़्यादा जानेंयहाँ.
  • Modifier.onFirstVisible() का इस्तेमाल अब नहीं किया जा सकता: Modifier.onVisibilityChanged() पर माइग्रेट करें. इससे, दिखने की थ्रेशोल्ड ट्रैकिंग ज़्यादा सटीक तरीके से की जा सकती है.

ग्राफ़िक

मेश ग्रेडिएंट्स

Compose 1.12 में, MeshGradientPainter को शामिल किया गया है. इससे आपको कई पॉइंट वाले, नैचुरल कलर ग्रेडिएंट बनाने में मदद मिलती है.

meshGradient.gif
val rows = 1
val columns = 1

val gradientPainter = remember {
    MeshGradientPainter(rows, columns) {
        // Parameters: row, column, position, color
        setVertex(0, 0, Offset(0f, 0f), Color.Red)     // Top-Left
        setVertex(0, 1, Offset(1f, 0f), Color.Blue)    // Top-Right
        setVertex(1, 0, Offset(0f, 1f), Color.Green)   // Bottom-Left
        setVertex(1, 1, Offset(1f, 1f), Color.Yellow)  // Bottom-Right
    }
}

Box(
    modifier = modifier
        .aspectRatio(16/9f)
        .fillMaxWidth()
        .paint(gradientPainter)
)

ज़्यादा जानकारी और उदाहरणों के लिए, दस्तावेज़ देखें.

वाइड कलर गैमट और एचडीआर सपोर्ट

मॉडर्न डिसप्ले में, ज़्यादा सटीक रंग और बेहतर डाइनैमिक रेंज मिलती है. Compose 1.12 में, Compose के ग्राफ़िक्स, पेंट, और शेडर में वाइड कलर गैमट (P3) और एचडीआर रेंडरिंग के लिए, पूरी पाइपलाइन की सुविधा चालू कर दी गई है. नॉन-एसआरजीबी कलर स्पेस (जैसे, Display P3) में तय किए गए रंगों को, प्लैटफ़ॉर्म रेंडरिंग के दौरान सुरक्षित रखा जाता है. इसमें कलर क्लैंपिंग नहीं होती. अगर रंग, ऐसे कलर स्पेस का इस्तेमाल करते हैं जो काम नहीं करता (जैसे, CieXyz, CieLab या Oklab), Android के ऐसे वर्शन पर कलर स्पेस का इस्तेमाल करते हैं जो काम नहीं करता (जैसे, Android 13 और इससे पहले के वर्शन पर Bt2020Hlg) या ऐप्लिकेशन Android 9 (एपीआई 28) और इससे पहले के वर्शन पर चल रहा है, तो रंग सुरक्षित तरीके से sRGB पर वापस आ जाएंगे.

अन्य ज़रूरी बदलाव:

  • LayerOutsets को GraphicsLayer और Modifier.graphicsLayer में जोड़ा गया है. इसका इस्तेमाल करके, लेयर के विज़ुअल बाउंड को उसके मेज़र किए गए साइज़ से ज़्यादा बढ़ाया जा सकता है. जब लेयर को ऑफ़स्क्रीन बफ़र में प्रमोट किया जाता है, तब clipToBounds के डिफ़ॉल्ट व्यवहार से बचने के लिए, LayerOutsets लागू करें.

स्टाइल

Google I/O में, हमने Compose Styles API के बारे में बताया था. यह कॉम्पोनेंट को स्टाइल करने का एक बेहतर और आसान तरीका है. इसके बाद से, हम बुनियादी आर्किटेक्चर को बेहतर बनाते रहे हैं, ताकि टाइप की सुरक्षा और अनुमानित सटीकता की गारंटी दी जा सके. साथ ही, कस्टम डिज़ाइन सिस्टम बनाने में मदद मिल सके. 

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

रनटाइम ऑप्टिमाइज़ेशन

Keyed SideEffect Overload

SideEffect अब मुख्य तर्कों के साथ काम करता है. इससे, खास कुंजियों में बदलाव होने पर, साइड इफ़ेक्ट को एक बार में ट्रिगर किया जा सकता है. जब आपको को-रूटीन या डिस्पोज़ ब्लॉक की ज़रूरत नहीं होती है, तब LaunchedEffect या DisposableEffect का इस्तेमाल करने की तुलना में, इसका इस्तेमाल करने से बेहतर परफ़ॉर्मेंस मिल सकती है. SideEffect, LaunchedEffect की तुलना में 90% तक और DisposableEffect की तुलना में 20% तक ज़्यादा तेज़ है. ध्यान दें कि SideEffect, DisposableEffect और LaunchedEffect से पहले काम करता है. इसलिए, अगर मौजूदा इफ़ेक्ट को इस एपीआई पर माइग्रेट किया जा रहा है, तो सावधानी बरतें. खास तौर पर, LaunchedEffects के लिए, जो मौजूदा फ़्रेम पूरा होने के बाद शुरू होने के लिए डिस्पैच किए जाने पर निर्भर करता है. 

@Composable
fun AnalyticsTracker(userId: String, screenName: String) {
    SideEffect(key1 = userId, key2 = screenName) {
        analytics.logScreenView(userId, screenName)
    }
}

ऐनिमेशन

  • DeferredTargetAnimation को एक्सपेरिमेंट के तौर पर इस्तेमाल करने की सुविधा अब उपलब्ध नहीं है. 

इंटरैक्टिव दो-स्टेज ट्रांज़िशन

  • नए कंपोज़ेबलDeferredAnimatedContent और DeferredAnimatedVisibility की मदद से, दो चरणों वाले शानदार ट्रांज़िशन बनाए जा सकते हैं. जैसे, पीछे जाने पर झलक दिखाने वाले हाथ के जेस्चर को ट्रैक करने के लिए.
  • ऐनिमेशन को मैन्युअल तरीके से कंट्रोल करना: ट्रांज़िशन के डेफ़र्ड फ़ेज़ के दौरान, ऐनिमेटेड प्रॉपर्टी (जैसे, स्केल या ऑफ़सेट) को अब रीयल-टाइम में मैन्युअल तरीके से बदला जा सकता है. उदाहरण के लिए, स्वाइप जेस्चर को ट्रैक करना.
  • बिना किसी रुकावट के ट्रांज़िशन: ट्रांज़िशन में देरी होने की अवधि खत्म होने के बाद, ट्रांज़िशन इंजन काम करना शुरू कर देता है. यह बिना किसी रुकावट के ट्रांज़िशन करता है. इसमें वेलोसिटी ट्रांसफ़र भी शामिल है.
  • शेयर किए गए एलिमेंट के लिए सहायता: SharedContentConfig में एक नया permitTransformDuringDeferredTransition फ़्लैग जोड़ा गया है. यह फ़्लैग यह कंट्रोल करता है कि डेफ़र्ड ट्रांज़िशन फ़ेज़ के दौरान, शेयर किए गए एलिमेंट अपने पैरंट कंटेनर के साथ विज़ुअल तौर पर बदलें या नहीं.
val state = remember { DeferredTransitionState(initialScreen) }
val transition = rememberDeferredTransition(state)

if (predictiveBackInProgress) {
    state.defer(targetScreen)
} else {
    state.animateTo(targetScreen)
}

transition.DeferredAnimatedContent(
    targetState = targetScreen,
    mutableTransformSpec = {
       MutableContentTransform {
           // Manually manipulate properties during the deferred phase
           initialContentTransform { scale = swipeProgress }
       }
    }
) { screen ->
    ScreenContent(screen)
}

यहां दो डेमो दिए गए हैं. इनमें, जेस्चर से कंट्रोल किए जाने वाले ऐनिमेशन को ट्रिगर किए गए ऐनिमेशन में बदल दिया जाता है:

colorCards.gif

पाठ, इनपुट और प्लेटफ़ॉर्म एकीकरण

संपादन योग्य पाठ स्वरूपण

नए एपीआई BasicTextField में संपादन योग्य पाठ के लिए समृद्ध-पाठ स्वरूपण प्रदान करते हैं. अब SpanStyle और ParagraphStyle का इस्तेमाल करके, प्रोग्राम के हिसाब से इनलाइन वर्ण और पैराग्राफ़ फ़ॉर्मैटिंग लागू की जा सकती है और उनमें बदलाव किया जा सकता है. इसके लिए, TextFieldBuffer स्कोप में मौजूद नए addStyle() तरीके का इस्तेमाल करें. जैसे, textFieldState.edit { ... } या InputTransformation में. इसके अलावा, TextFieldBuffer, getSpanStyles() और getParagraphStyles() एपीआई उपलब्ध कराता है. ये TrackedRange ऑब्जेक्ट दिखाते हैं. इनकी मदद से, लागू की गई स्टाइल को पढ़ा, अपडेट किया जा सकता है या हटाया जा सकता है. फ़ॉर्मेटिंग निर्माण को पूरक करने के लिए, TextFieldState अब श्रेणियों में सक्रिय शैलियों को क्वेरी करने के लिए एक रीड-ओनली textStyles प्रॉपर्टी को उजागर करता है, जबकि TextFieldBuffer संपादन से पहले फ़ॉर्मेटिंग स्थिति का निरीक्षण करने के लिए originalTextStyles प्रदान करता है. कॉन्फ़िगरेशन में बदलाव होने पर भी, टेक्स्ट फ़ॉर्मैटिंग और कस्टम एनोटेशन बने रहते हैं.

val state = rememberTextFieldState("Formatted text in Compose 1.12")

// Apply bold and color styles to a range of text
state.edit {
    addStyle(
        SpanStyle(fontWeight = FontWeight.Bold, color = Color.Blue),
        start = 0,
        end = 9
    )
}

// Query active styles from TextFieldState
val currentStyles = state.textStyles

टेक्स्ट चुनना

नए SelectionState एपीआई की मदद से, SelectionContainer में टेक्स्ट चुनने की सुविधा को प्रोग्राम के हिसाब से कंट्रोल किया जा सकता है. साथ ही, यह भी देखा जा सकता है कि टेक्स्ट को कैसे चुना जा रहा है. rememberSelectionState() के माध्यम से SelectionState ऑब्जेक्ट को होस्ट करना और SelectionContainer में पास करना selectedTexts को AnnotatedStrings की एक प्रतिक्रियाशील सूची के रूप में उजागर करता है और selectAll()clear()select(TextRange), और extendSelectionByWord() जैसी विधियाँ प्रदान करता है.

इसके अलावा, लेआउट के क्रम में चुने जा सकने वाले सभी टेक्स्ट आइटम को वापस पाने के लिए, getSelectableTexts() का इस्तेमाल करें. साथ ही, ग्लोबल रेंज का इस्तेमाल करके SelectionContainer में कंपोज़ेबल के बीच टेक्स्ट चुनें. 

@Composable
fun ProgrammaticSelectionExample() {
    val selectionState = rememberSelectionState()

    Column {
        Button(
            onClick = { selectionState.selectAll() },
            modifier = Modifier.disableSelectionClearOnTap()
        ) {
            Text("Select All")
        }

        SelectionContainer(state = selectionState) {
            Text("Text content to be selected programmatically.")
        }
    }
}

Credential Manager इंटिग्रेशन

टेक्स्ट फ़ील्ड अब Android के Credential Manager (API 34+) के साथ नेटिव तौर पर इंटिग्रेट हो जाते हैं. ऐसा, Autofill फ़्रेमवर्क के ज़रिए होता है. API 34 से पहले के वर्शन में, इसे androidx.credentials library मैनेज करता है. नई credentialRequest सिमैंटिक्स प्रॉपर्टी को CredentialRequestData के साथ अटैच करके, टेक्स्ट इनपुट सीधे तौर पर पासकी, सेव किए गए क्रेडेंशियल या साइन-इन के अनुरोधों को प्रॉम्प्ट कर सकते हैं. ऐसा, उपयोगकर्ता के इनपुट फ़्लो के दौरान किया जा सकता है.

@Composable
fun LoginField(textFieldState: TextFieldState) {
    val credentialData = remember {
        CredentialRequestData(
            // Specify Credential Manager request options
        )
    }

    BasicTextField(
        state = textFieldState,
        modifier = Modifier.semantics {
            credentialRequest = credentialData
        }
    )
}

अन्य ज़रूरी बदलाव:

  • डाउनलोड किए जा सकने वाले फ़ॉन्ट में, फ़ॉन्ट वैरिएशन सेटिंग के लिए सहायता जोड़ी गई है.
  • SelectionContainer में, टेक्स्ट को व्यूपोर्ट से बाहर ले जाकर चुनने पर, अपने-आप स्क्रोल होने की सुविधा चालू की गई.
  • Compose कॉम्पोनेंट में, अपने-आप इंटरैक्शन की आवाज़ें (क्लिक और फ़ोकस नेविगेशन) चलाने की सुविधा जोड़ी गई है. साथ ही, ऑप्ट-आउट करने के लिए नया SoundEffectOnInteraction कंपोज़ेबल जोड़ा गया है. ध्यान दें कि इस बदलाव के बाद, सिमैंटिक्स क्लिक लिसनर को मुख्य थ्रेड से कॉल करना होगा. इससे कुछ टेस्ट केस पर असर पड़ सकता है.
  • KeyboardType में अब DateTimeDateTime, और SignedDecimal शामिल हैं.
  • BasicSecureTextField अब डिफ़ॉल्ट रूप से TextObfuscationMode.System का इस्तेमाल करता है. वहीं, RevealLastTyped का इस्तेमाल पूरी तरह से ओवरराइड करने के लिए किया जाता है.

लेआउट को बेहतर बनाने की सुविधा

ग्रिड लेआउट में नामित क्षेत्र

@Experimental ग्रिड कॉम्पोनेंट में, नाम वाली जगहों की मदद से अब 2D लेआउट बनाना आसान हो गया है. सभी आइटम के लिए, संख्या वाले कॉलम और लाइन इंडेक्स को मैनेज करने के बजाय, अपने GridConfigurationScope में सिमैंटिक रीजन तय किए जा सकते हैं. साथ ही, एरिया के नाम के हिसाब से कंपोज़ेबल को पोज़िशन किया जा सकता है.

@OptIn(ExperimentalGridApi::class)
@Composable
fun DashboardLayout() {
    Grid(
        config = {
            area("header", row = 0, column = 0, rowSpan = 1, columnSpan = 2)
            area("sidebar", row = 1, column = 0)
            area("content", row = 1, column = 1)
            gap(16.dp)
        }
    ) {
        HeaderSection(modifier = Modifier.gridItem(areaId = "header"))
        NavigationSidebar(modifier = Modifier.gridItem(areaId = "sidebar"))
        MainContentView(modifier = Modifier.gridItem(areaId = "content"))
    }
}

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

परफ़ॉर्मेंस

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

timetoinitialdisplay@2x _v2.png

परीक्षण और टूलिंग अपग्रेड

टेस्ट सिंक करना

Compose 1.12 में नए टेस्ट API पेश किए गए हैं जिन्हें टेस्ट निष्पादन समय को कम करने और स्टेट सैंपलिंग के दौरान अस्थिरता को दूर करने के लिए डिज़ाइन किया गया है:

  • hasPendingWork: घड़ी को आगे बढ़ाए बिना निष्क्रिय रूप से जांच करता है कि क्या यूआई में लंबित कार्य है, जो मैन्युअल एनीमेशन लूप के लिए आदर्श है.
  • runWithoutImplicitWait: मैन्युअल क्लॉक फ़्रेमों के माध्यम से आगे बढ़ते समय (जैसे एनीमेशन परीक्षण) अंतर्निहित सिंक्रनाइज़ेशन को अस्थायी रूप से अक्षम करता है.
@Test
fun testAnimationStateFast() {

composeTestRule.mainClock.autoAdvance = false
    
    while (composeTestRule.hasPendingWork()) {
        composeTestRule.mainClock.advanceTimeByFrame()
        composeTestRule.waitForIdle()
        
        composeTestRule.runOnUiThread {
            composeTestRule.runWithoutImplicitWait {
                // This is most effective when querying multiple nodes in a single frame. 
                // It prevents the redundant synchronization overhead that would 
                // otherwise occur on every individual query.
                val box1 = composeTestRule.onNodeWithTag("Box1").fetchSemanticsNode()
                val box2 = composeTestRule.onNodeWithTag("Box2").fetchSemanticsNode()
                
                assertThat(box1.boundsInRoot.right).isAtMost(box2.boundsInRoot.left)
            }
        }
    }
}

अन्य ज़रूरी बदलाव:

  • captureToImage एपीआई की मदद से, अब पॉप-अप या डायलॉग को उसके ऐंकर के साथ एक ही बिटमैप में कैप्चर किया जा सकता है.
  • Compose की सिमैंटिक खोजों को खास Android व्यू तक सीमित करने के लिए, onRootWithViewInteraction जोड़ा गया. इससे हाइब्रिड यूज़र इंटरफ़ेस (यूआई), जैसे कि RecyclerViews की टेस्टिंग आसान हो जाती है. इसके लिए, प्रोडक्शन कोड में यूनीक टेस्ट टैग की ज़रूरत नहीं होती.
  • @PreviewWrapper एनोटेशन अब कस्टम @MultiPreview क्लास पर लागू किए जा सकते हैं, जिससे कई घटकों में पुन: प्रयोज्य पूर्वावलोकन सेटअप (जैसे कस्टम थीम) सक्षम हो जाते हैं.

संगीत कंपोज़ करने का आनंद लें!

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

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