لماذا لا تستجيب Column؟ لعنة التوسيط في Jetpack Compose
\nهل جلست يومًا في الليل مع فنجان قهوة، تكتب كودًا بلغة Kotlin لـ Jetpack Compose وفجأة لاحظت أن Column الخاصة بك ترفض بعناد توسيط المحتوى؟ تضيف Modifier.align(Alignment.CenterHorizontally) — ولكن النص لا يزال ملتصقًا بالحافة اليسرى. هل هذا مألوف؟
هذه المشكلة هي ضجة حقيقية على Stack Overflow. آلاف المطورين (وأنا منهم) ضربوا رؤوسهم بالشاشة محاولين فهم أين اختفى "gravity center". في هذه المقالة، سنستعرض أهم الأخطاء التي تحول Column الخاصة بك إلى قائمة غير قابلة للتحكم، ونتعلم كيفية تجنبها. استعدوا: سيكون هناك الكثير من الكود، أمثلة حية، ولا ماء زائد.
\n\nالخطأ رقم 1: الخلط بين Column و Row
\nأول وأكثر فخ شائع هو نقل العادات من Android XML الكلاسيكي. هناك، كان لدى LinearLayout الخاصية gravity="center". في Compose، الأمر مختلف تمامًا.
الفرق الرئيسي: Column ترتب العناصر عموديًا. لذلك، "التوسيط الأفقي" ليس خاصية لـ Column نفسها، بل هو سلوك لعناصرها الفرعية. إذا كتبت:
Column(\n modifier = Modifier.fillMaxSize(),\n horizontalAlignment = Alignment.CenterHorizontally\n) {\n Text("مرحبًا بالعالم!")\n}\nهنا يعمل horizontalAlignment، ولكن فقط إذا كان Text نفسه غير مقيد بالعرض. أما إذا كان لديك Modifier.fillMaxWidth() على العنصر الفرعي — فسينهار التوسيط. لماذا؟ لأن العنصر يتمدد ليشغل العرض بالكامل، ولا يتبقى شيء لتوسيطه داخله.
الخطأ رقم 2: استخدام Modifier.align() بدلاً من horizontalAlignment
\nهذا كود فخ كلاسيكي يتداول على Stack Overflow:
\nColumn(\n modifier = Modifier.fillMaxSize()\n) {\n Text(\n text = "يجب أن أكون في المنتصف",\n modifier = Modifier.align(Alignment.CenterHorizontally)\n )\n}\nللوهلة الأولى — يبدو منطقيًا. لكن هذا لن يعمل إذا لم يتم تعيين horizontalAlignment لـ Column. السبب هو أن Modifier.align() هو معدل خاص بـ Box و ColumnScope. إنه متاح فقط داخل Column، ولكنه يعمل بالتزامن مع horizontalAlignment. إذا لم يتم تحديد الأخير، يتم تجاهل align ببساطة.
كيفية الإصلاح:
\nColumn(\n modifier = Modifier.fillMaxSize(),\n horizontalAlignment = Alignment.CenterHorizontally // إلزامي!\n) {\n Text(\n text = "الآن أنا في المنتصف",\n modifier = Modifier.align(Alignment.CenterHorizontally) // اختياري\n )\n}\n\nالخطأ رقم 3: نسيان Arrangement للتوسيط الرأسي
\nغالبًا ما يرغب المطورون في توسيط محتوى Column رأسيًا (على المحور Y). هنا يأتي دور verticalArrangement:
Column(\n modifier = Modifier.fillMaxSize(),\n verticalArrangement = Arrangement.Center,\n horizontalAlignment = Alignment.CenterHorizontally\n) {\n Text("مركز الكون")\n Button(onClick = { }) { Text("زر") }\n}\nلكن هناك فارق بسيط: Arrangement.Center سيعمل فقط إذا كانت Column تشغل الارتفاع الكامل للشاشة (Modifier.fillMaxSize() أو Modifier.height(IntrinsicSize.Min)). إذا كان ارتفاع Column يساوي مجموع ارتفاعات العناصر الفرعية — فلن يكون هناك مجال للتوسيط.
الخطأ رقم 4: IntrinsicSize والسلوك غير المتوقع
\nأحيانًا تضيف Modifier.height(IntrinsicSize.Min) لجعل Column تنكمش حسب المحتوى. وهنا ينهار التوسيط الرأسي:
Column(\n modifier = Modifier\n .fillMaxWidth()\n .height(IntrinsicSize.Min),\n verticalArrangement = Arrangement.Center\n) {\n Text("نص 1")\n Text("نص 2")\n}\nالمشكلة:
المدونات
توصيات الكتب
اقرأ أيضًا