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 کے برعکس جہاں خواص setter کے ذریعے مقرر کی جاتی تھیں (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) 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 ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں