Modifier Jetpack Compose में एक अपरिवर्तनीय ऑब्जेक्ट है जो UI घटक के गुणों को परिभाषित करता है: आकार, पैडिंग, पृष्ठभूमि, जेस्चर हैंडलिंग और व्यवहार। मॉडिफायर अनुक्रमिक कॉल के माध्यम से एक श्रृंखला में संयोजित होते हैं, और उनके अनुप्रयोग का क्रम परिणाम को महत्वपूर्ण रूप से प्रभावित करता है। Google Android Developers, 2026 के अनुसार, Modifier का सही उपयोग घोषणात्मक UI में लचीला और कुशल इंटरफ़ेस बनाने का आधार है।
मुख्य बिंदु
Modifier androidx.compose.ui पैकेज का एक इंटरफ़ेस है जो Composite पैटर्न को लागू करता है। प्रत्येक मॉडिफायर एक श्रृंखला तत्व है जो पिछले को लपेटता है और अपना स्वयं का व्यवहार जोड़ता है। Modifier अपरिवर्तनीय है — कोई भी परिवर्तन श्रृंखला में एक नया तत्व जोड़कर प्रतिलिपि के माध्यम से एक नया ऑब्जेक्ट बनाता है। यह एक Modifier को कई घटकों के बीच सुरक्षित रूप से साझा करने की अनुमति देता है।
मूल मॉडिफायर फ़ंक्शन साथी ऑब्जेक्ट Modifier के माध्यम से कॉल किए जाते हैं (उदाहरण के लिए, Modifier.padding(), Modifier.fillMaxWidth())। प्रत्येक फ़ंक्शन जोड़े गए तत्व के साथ एक नया Modifier लौटाता है। यदि कई मॉडिफायर हैं, तो वे एक श्रृंखला में संयोजित होते हैं: Modifier.padding(16.dp).fillMaxWidth().background(Color.Blue)। क्रम UI तत्व के सापेक्ष बाहर से अंदर की ओर होता है।
पारंपरिक View के विपरीत जहां गुण setters के माध्यम से सेट किए जाते थे (view.setPadding(...), view.setBackground(...)), Compose में Modifier एक घोषणात्मक विवरण है। घटक रनटाइम पर मॉडिफायर को "लागू" नहीं करता — LayoutNode संरचना के दौरान Modifier श्रृंखला को पार करता है और Modifier.Element की एक सूची बनाता है, जिसे बाद में माप और लेआउट चरणों के दौरान संसाधित किया जाता है।
मॉडिफायर का क्रम Compose में सबसे आम गलतियों में से एक है। प्रत्येक मॉडिफायर पिछले को लपेटता है, और संचालन बाहर से अंदर की ओर लागू होते हैं। उदाहरण के लिए, padding(16.dp).clickable { }: पहले तत्व के चारों ओर पैडिंग जोड़ी जाती है, फिर क्लिक क्षेत्र में पैडिंग शामिल होती है। clickable { }.padding(16.dp): क्लिक क्षेत्र पहले तत्व के आकार के बराबर होता है, फिर उसके चारों ओर पैडिंग जोड़ी जाती है — पैडिंग पर क्लिक काम नहीं करेगा।
याद रखने का नियम: श्रृंखला को बाएँ से दाएँ पढ़ें और बाहर से अंदर की ओर लागू करें। पहला मॉडिफायर सबसे बाहरी है, जो तत्व के चारों ओर के क्षेत्र पर लागू होता है। अंतिम सबसे भीतरी है, जो सीधे सामग्री पर लागू होता है। आकार मॉडिफायर (size, fillMaxWidth) को पैडिंग के बाद आना चाहिए यदि पैरेंट से पैडिंग की आवश्यकता है, या पैडिंग से पहले यदि सामग्री को पहले सीमित किया जाना चाहिए और फिर केंद्रित किया जाना चाहिए।
उदाहरण: size(100.dp).padding(10.dp) — निश्चित आकार 100dp का तत्व, फिर बाहर 10dp पैडिंग (अंतिम आकार 120dp)। padding(10.dp).size(100.dp) — 10dp पैडिंग उपलब्ध स्थान को (पैरेंट - 20dp) तक कम कर देती है, फिर size(100dp) पैरेंट से बाहर निकल सकता है। परिणाम सत्यापित करने के लिए प्रदर्शन परीक्षणों का उपयोग करते हुए हमेशा क्रम के बारे में सोच-समझकर निर्णय लें।
| क्रम | परिणाम |
|---|---|
| padding → clickable | क्लिक पैडिंग क्षेत्र पर भी काम करता है |
| clickable → padding | क्लिक केवल सामग्री पर काम करता है, पैडिंग डेड ज़ोन है |
| size → padding | तत्व size(100), बाहर पैडिंग → 100+2*pad |
| padding → size | पैडिंग स्थान कम करती है, size सीमा से बाहर जा सकता है |
| background → padding | पृष्ठभूमि बाहरी क्षेत्र सहित पूरे तत्व को भरती है |
| padding → background | पृष्ठभूमि केवल पैडिंग के अंदर (बाहरी क्षेत्र पारदर्शी) |
मानक Compose लाइब्रेरी में ~50+ मॉडिफायर श्रेणियों में विभाजित हैं। आकार और स्थिति निर्धारण: Modifier.size(), width(), height(), fillMaxSize(), fillMaxWidth(), fillMaxHeight(), defaultMinSize(), requiredSize()। पैडिंग और सीमाएँ: padding(), offset(), margin (पैरेंट की पैडिंग या Layout के माध्यम से सेट)। सजावट: background(), border(), clip(), alpha(), shadow(), blur()।
व्यवहार और जेस्चर: clickable(), combinedClickable(), pointerInput(), draggable(), swipeable()। कंटेनर में व्यवस्था: weight() (Row/Column के लिए), align(), alignBy(), matchParentSize()। सिमैंटिक्स और एक्सेसिबिलिटी: semantics(), testTag(), clearAndSetSemantics()। ड्राइंग: drawBehind(), drawWithContent(), drawModifier() — कैनवास पर कस्टम ड्राइंग की अनुमति देने वाले मॉडिफायर।
सिमैंटिक मॉडिफायर एक विशेष श्रेणी है। Modifier.semantics {} परिभाषित करता है कि तत्व एक्सेसिबिलिटी ट्री में कैसे प्रस्तुत किया जाएगा। Compose स्वचालित रूप से टेक्स्ट से सिमैंटिक्स भरता है, लेकिन कस्टम घटकों के लिए भूमिकाओं, स्थितियों और क्रियाओं को मैन्युअल रूप से सेट करने की आवश्यकता होती है। यह WCAG 2.2 अनुपालन और TalkBack (Android) और VoiceOver (iOS) के सही संचालन के लिए महत्वपूर्ण है।
@Composable
fun ModifierDemo() {
// सही क्रम के साथ मॉडिफायर श्रृंखला
Box(
modifier = Modifier
.size(150.dp)
.padding(8.dp)
.border(2.dp, Color.Gray)
.background(Color(0xFFE3F2FD))
.clickable { /* handle click */ }
.semantics {
contentDescription = "Demo card with click action"
role = Role.Button
}
) {
Text("मुझे स्पर्श करें")
}
}
Modifier.composed एक फ़ैक्टरी विधि है जो कंपोजिट मॉडिफायर बनाने की अनुमति देती है जो अन्य मॉडिफायर, LocalComposition और स्थानीय स्थिति का उपयोग कर सकते हैं। एक सामान्य एक्सटेंशन फ़ंक्शन के विपरीत, composed हर बार लागू होने पर एक इंस्टेंस बनाता है, जिससे मॉडिफायर की अपनी स्थिति हो सकती है।
composed का उपयोग कब करें: मॉडिफायर के आवर्ती संयोजन (उदाहरण के लिए, मानक कार्ड शैली: padding + background + border + clickable); स्थिति वाले मॉडिफायर (दबाने पर एनिमेटेड पृष्ठभूमि परिवर्तन); CompositionLocals तक पहुँच (MaterialTheme रंग योजना, पिक्सेल घनत्व)। सामान्य मामलों के लिए, composed के बिना एक सामान्य एक्सटेंशन फ़ंक्शन पर्याप्त है।
composed का प्रदर्शन: प्रत्येक कॉल एक नया मॉडिफायर ऑब्जेक्ट बनाता है, जो पुनर्संरचना के दौरान अतिरिक्त आवंटन का कारण बन सकता है। इसे रोकने के लिए, composed को remember में लपेटें। Google केवल तब composed का उपयोग करने की सलाह देता है जब वास्तव में अंदर स्थिति या CompositionLocal की आवश्यकता हो। स्थिर संयोजनों के लिए, सामान्य एक्सटेंशन फ़ंक्शन का उपयोग करें।
// स्थिति के साथ composed के माध्यम से कस्टम मॉडिफायर
fun Modifier.cardStyle(
elevation: Dp = 4.dp,
isSelected: Boolean = false
): Modifier = this.composed {
val backgroundColor = if (isSelected)
MaterialTheme.colorScheme.primaryContainer
else
MaterialTheme.colorScheme.surface
this
.fillMaxWidth()
.padding(12.dp)
.background(backgroundColor, RoundedCornerShape(8.dp))
.shadow(elevation, RoundedCornerShape(8.dp))
}
// उपयोग उदाहरण
@Composable
fun CardList() {
Column {
Box(Modifier.cardStyle()) { Text("आइटम 1") }
Box(Modifier.cardStyle(isSelected = true)) { Text("चयनित") }
}
}
// स्थिर संस्करण (composed के बिना) — तेज़
fun Modifier.simpleCardStyle(): Modifier =
this.fillMaxWidth().padding(8.dp).clip(RoundedCornerShape(4.dp))
प्रत्येक पुनर्संरचना पर Modifier को पुनः बनाने से बचें। यदि मॉडिफायर परिवर्तनीय डेटा पर निर्भर नहीं करता — इसे कॉन्स्टेंट या remember में ले जाएँ। Modifier.padding().background() का प्रत्येक कॉल नए Modifier.Element ऑब्जेक्ट बनाता है। एक पृथक घटक में यह नगण्य है, लेकिन सैकड़ों तत्वों वाले LazyColumn में, अतिरिक्त आवंटन स्क्रॉल करते समय ध्यान देने योग्य अंतराल पैदा करते हैं।
नियम: यदि मॉडिफायर श्रृंखला Composable फ़ंक्शन के मापदंडों पर निर्भर नहीं करती — इसे फ़ंक्शन के बाहर (फ़ाइल या Companion स्तर पर) val के रूप में घोषित करें। यदि निर्भर करती है — remember(निर्भरता) { ... } का उपयोग करें। उन मॉडिफायर के लिए जो हमेशा समान होते हैं, Composable के बाहर val सबसे कुशल है: ऐसे ऑब्जेक्ट एप्लिकेशन के पूरे जीवनकाल में एक बार बनाए जाते हैं।
Modifier क्रम के सर्वोत्तम अभ्यास: मॉडिफायर को तार्किक क्रम में रखें: पहले आकार/पैडिंग (लेआउट), फिर सजावट (background, border), फिर व्यवहार (clickable, pointerInput)। यह न केवल पठनीयता में सुधार करता है बल्कि Compose Runtime को माप के दौरान श्रृंखला को अनुकूलित करने में भी मदद करता है। विभिन्न Modifier के साथ अत्यधिक नेस्टेड Box से भी बचें — अक्सर पैरेंट कंटेनर पर एक Modifier 2-3 नेस्टेड को बदल सकता है।
// ✅ अच्छा: Composable के बाहर कॉन्स्टेंट
private val cardModifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(8.dp))
@Composable
fun CardContent() {
Box(cardModifier.background(Color.White)) { ... }
}
// ❌ बुरा: प्रत्येक पुनर्संरचना पर पुनर्निर्माण
@Composable
fun BadCard() {
Box(Modifier.fillMaxWidth().padding(16.dp)) { ... }
}
// ✅ अच्छा: गतिशील Modifier के लिए remember
@Composable
fun DynamicCard(color: Color) {
val modifier = remember(color) {
Modifier.fillMaxWidth().background(color)
}
Box(modifier) { ... }
}
अक्सर पूछे जाने वाले प्रश्न
हाँ, Modifier अपरिवर्तनीय है, इसलिए एक ऑब्जेक्ट का सुरक्षित रूप से कई स्थानों पर उपयोग किया जा सकता है। हालाँकि, यदि आप composed मॉडिफायर का उपयोग करते हैं, तो प्रत्येक कॉल एक नया इंस्टेंस बनाता है। स्थिर श्रृंखलाओं के लिए, Composable के बाहर कॉन्स्टेंट या val सबसे अच्छा समाधान है।
Android Studio में Layout Inspector का उपयोग करें — यह प्रत्येक Modifier की सीमाओं को दृश्य रूप से दिखाता है। प्रोग्रामेटिक डीबगिंग के लिए, श्रृंखला के प्रत्येक चरण पर अलग-अलग रंगों के साथ Modifier.border() जोड़ें ताकि प्रत्येक मॉडिफायर की सीमाएँ देखी जा सकें।
Modifier.then(other) अन्य श्रृंखला को this से जोड़ता है। अनुक्रमिक कॉल (Modifier.a().b()) Modifier.then(a()).then(b()) के समतुल्य हैं। कोई अंतर नहीं है — यह वही श्रृंखला तंत्र है। then() उपयोगी है जब आपको किसी वेरिएबल से तैयार श्रृंखला को संलग्न करने की आवश्यकता होती है।
Modifier.semantics {} परिभाषित करता है कि तत्व स्क्रीन रीडर के लिए कैसे वर्णित किया जाएगा। Modifier.clickable() स्वचालित रूप से बटन भूमिका और Action(OnClick) जोड़ता है। कस्टम जेस्चर के लिए, आपको स्पष्ट रूप से semantics निर्दिष्ट करना होगा। सिमैंटिक मॉडिफायर के बिना, TalkBack उपयोगकर्ता कस्टम घटकों के साथ बातचीत नहीं कर पाएंगे।
Modifier.background(color, shape) कोनों के साथ काम करता है, लेकिन कोनों को काटने के लिए clip() को background से पहले आना चाहिए। सही क्रम: clip(shape).background(color)। यदि आपको अंदर की सामग्री को भी काटने की आवश्यकता है, तो पैरेंट पर clipToBounds() का उपयोग करें।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें