🧱 ما هي Row في Flutter؟
Rowهي ويدجت تُستخدم لترتيب العناصر (Widgets) أفقيًا بجانب بعضها البعض (من اليسار إلى اليمين أو من اليمين إلى اليسار بحسب اتجاه اللغة).
Row(
children: [
Icon(Icons.star),
Text('نجمة'),
],
)Dart🧩 متى تستخدم Row؟
تُستخدم Row عندما تريد:
- ترتيب عدة ويدجت في صف أفقي واحد.
- وضع أزرار أو أي عناصر جنبًا إلى جنب.
- بناء واجهات بسيطة مثل: شريط أدوات، قائمة أفقية، أو عرض بيانات بشكل أفقي.
📌 الخصائص الأساسية في Row
1. children
القائمة التي تحتوي على الودجات التي سيتم عرضها أفقيًا.
Row(
children: [
Icon(Icons.home),
Text('الصفحة الرئيسية'),
],
)Dart2. mainAxisAlignment
تتحكم في توزيع العناصر على المحور الأفقي (Main Axis).
| القيمة | التأثير |
|---|---|
MainAxisAlignment.start | محاذاة من البداية (اليسار أو اليمين حسب اللغة) |
MainAxisAlignment.end | محاذاة من النهاية |
MainAxisAlignment.center | توسيط العناصر |
MainAxisAlignment.spaceBetween | توزيع العناصر مع ترك فراغات متساوية بين العناصر فقط |
MainAxisAlignment.spaceAround | توزيع العناصر مع ترك فراغات بين العناصر وحولها |
MainAxisAlignment.spaceEvenly | توزيع العناصر مع فراغات متساوية تمامًا |
🧠 المحور الأفقي = Row = Main Axis
3. crossAxisAlignment
تتحكم في محاذاة العناصر على المحور العمودي (Cross Axis).
| القيمة | التأثير |
|---|---|
CrossAxisAlignment.start | محاذاة العناصر إلى الأعلى |
CrossAxisAlignment.end | محاذاة العناصر إلى الأسفل |
CrossAxisAlignment.center | توسيط العناصر عموديًا |
CrossAxisAlignment.stretch | تمديد العناصر لملء الارتفاع |
CrossAxisAlignment.baseline | محاذاة بناءً على خط الأساس للنص (يحتاج textBaseline) |
🧠 Cross Axis في Row هو المحور العمودي (الارتفاع).
4. mainAxisSize
تحدد هل تأخذ
Rowكل عرض الشاشة أو فقط على قدر محتواها.
| القيمة | التأثير |
|---|---|
MainAxisSize.max | يأخذ كل العرض المتاح (افتراضي) |
MainAxisSize.min | يأخذ فقط عرض العناصر بداخله |
Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.star),
Text('محدود'),
],
)Dart5. textDirection
اتجاه عرض العناصر (LTR أو RTL)
| القيمة | التأثير |
|---|---|
TextDirection.ltr | من اليسار لليمين |
TextDirection.rtl | من اليمين لليسار |
6. verticalDirection
يحدد ترتيب العناصر العمودي (متى نستخدم CrossAxisAlignment).
| القيمة | التأثير |
|---|---|
VerticalDirection.down | من الأعلى للأسفل (افتراضي) |
VerticalDirection.up | من الأسفل للأعلى |
7. clipBehavior
إذا تجاوزت الودجات حدود
Row، هل يتم قصّها أم لا؟
| القيمة | التأثير |
|---|---|
Clip.none | لا يتم القصّ (افتراضي) |
Clip.hardEdge, antiAlias… | يتم القصّ بأنماط مختلفة |
🎯 مثال عملي شامل:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Icon(Icons.home, size: 32),
Text(
'الرئيسية',
style: TextStyle(fontSize: 20),
),
Icon(Icons.settings, size: 32),
],
)
Dart💡 ملاحظات مهمة:
Rowلا تقوم بالتمرير تلقائيًا إذا زادت العناصر عن عرض الشاشة. لحل هذا:
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [...],
),
)Dart- يجب أن تكون كل العناصر داخل
Rowبويدجت يمكنها أن تعمل داخل صف أفقي. إذا أردت عنصر يأخذ عرضًا أكبر، استخدمExpandedأوFlexible.
🔁 الفرق بين Expanded و Flexible (داخل Row)
✅ Expanded
يملأ المساحة المتاحة الباقية.
Row(
children: [
Expanded(child: Text('هذا يأخذ كل المساحة الباقية')),
Icon(Icons.arrow_forward),
],
)Dart✅ Flexible
يسمح بتعديل المساحة، لكن لا يُجبر العنصر على الامتداد الكامل.
Row(
children: [
Flexible(child: Text('هذا مرن')),
Icon(Icons.arrow_forward),
],
)Dart🧱 مقارنة مختصرة مع Column
| العنصر | Row | Column |
|---|---|---|
| المحور الأساسي | أفقي | عمودي |
mainAxisAlignment | يتحكم في العرض | يتحكم في الارتفاع |
crossAxisAlignment | يتحكم في الارتفاع | يتحكم في العرض |
✅ خلاصة
| النقطة | Row |
|---|---|
| ترتيب أفقي للعناصر | ✔️ |
| يدعم المحاذاة الرأسية | ✔️ عبر crossAxisAlignment |
| لا يلف تلقائيًا | ❌ (يحتاج Scroll أو Wrap) |
| يستخدم كثيرًا في التصميمات البسيطة والاحترافية | ✔️ |