GridView

🔍 ما هي GridView؟

GridView هي ويدجت في Flutter تسمح لك بعرض قائمة من العناصر في شكل شبكة (شبكة أعمدة وصفوف)، ويمكن تمريرها عموديًا أو أفقيًا.

مثل: عرض صور، بطاقات، منتجات، أو أي عناصر تحتاج ترتيب على شكل شبكة.

🧠 متى تستخدم GridView؟
  • عند الحاجة لعرض عناصر بشكل صفوف وأعمدة (2D).
  • لعرض بطاقات، صور، منتجات بترتيب مرن.
  • عندما لا يناسب ListView الشكل المطلوب.
✅ أنواع GridView
النوعالاستخدام
GridView.count()تحديد عدد الأعمدة بشكل مباشر
GridView.builder()بناء الشبكة بشكل ديناميكي (أفضل للأداء)
GridView.extent()تحديد أقصى عرض لكل عنصر
GridView.custom()مخصص بالكامل (نادرًا ما يُستخدم)
📌 النوع الأول: GridView.count

أسهل طريقة لبناء شبكة عناصر عبر تحديد عدد الأعمدة.

GridView.count(
  crossAxisCount: 3, // عدد الأعمدة
  children: List.generate(9, (index) {
    return Container(
      alignment: Alignment.center,
      color: Colors.amber,
      child: Text('عنصر $index'),
    );
  }),
)
Dart
📌 النوع الثاني: GridView.builder

الأفضل من حيث الأداء (يبني العناصر حسب الحاجة فقط)

GridView.builder(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2,
    crossAxisSpacing: 10,
    mainAxisSpacing: 10,
  ),
  itemCount: 20,
  itemBuilder: (context, index) {
    return Container(
      color: Colors.blue,
      child: Center(child: Text('عنصر $index')),
    );
  },
)
Dart
📌 gridDelegate — مهم جدًا!

هناك نوعان رئيسيان:

1. SliverGridDelegateWithFixedCrossAxisCount

تحديد عدد الأعمدة بشكل ثابت

SliverGridDelegateWithFixedCrossAxisCount(
  crossAxisCount: 2,
  crossAxisSpacing: 10,
  mainAxisSpacing: 10,
  childAspectRatio: 1.5, // العرض مقابل الارتفاع
)
Dart
2. SliverGridDelegateWithMaxCrossAxisExtent

تحديد العرض الأقصى لكل عنصر (وليس عدد الأعمدة)

SliverGridDelegateWithMaxCrossAxisExtent(
  maxCrossAxisExtent: 200,
  crossAxisSpacing: 10,
  mainAxisSpacing: 10,
)
Dart
📌 الخصائص العامة لـ GridView
الخاصيةالشرح
scrollDirectionالاتجاه: عمودي (افتراضي) أو أفقي
paddingحواف داخلية للمحتوى
shrinkWrapهل تأخذ حجم المحتوى فقط؟
physicsنوع التمرير (مثل Bouncing)
reverseهل تبدأ التمرير من الأسفل؟
primaryهل تستخدم ScrollController افتراضيًا؟
✅ مثال كامل واقعي:
GridView.builder(
  padding: EdgeInsets.all(16),
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3,
    crossAxisSpacing: 10,
    mainAxisSpacing: 10,
    childAspectRatio: 0.75,
  ),
  itemCount: 12,
  itemBuilder: (context, index) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.teal,
        borderRadius: BorderRadius.circular(8),
      ),
      child: Center(
        child: Text(
          'عنصر $index',
          style: TextStyle(color: Colors.white),
        ),
      ),
    );
  },
)
Dart
🧠 ملاحظات مهمة
  • GridView تتطلب gridDelegate لتحديد طريقة توزيع العناصر.
  • استخدم GridView.builder بدلاً من count إذا كنت تبني عناصر كثيرة ديناميكيًا.
  • يمكنك جعل الشبكة أفقية بإضافة: dartCopyEditscrollDirection: Axis.horizontal
🧰 استخدام مع صور:
GridView.builder(
  itemCount: 6,
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
  itemBuilder: (context, index) {
    return Image.network(
      'https://picsum.photos/200?image=$index',
      fit: BoxFit.cover,
    );
  },
)
Dart
✅ مقارنة سريعة بين ListView و GridView
ListViewGridView
الشكلعمودي أو أفقيصفوف وأعمدة
التمريرسهلسهل
أداء كبيراستخدم builderاستخدم builder
استخداماتقوائم – دردشةصور – منتجات – شبكات
💡 الخلاصة
الخاصيةالمعنى
crossAxisCountعدد الأعمدة
mainAxisSpacingمسافة عمودية بين العناصر
crossAxisSpacingمسافة أفقية
childAspectRatioنسبة العرض إلى الارتفاع
maxCrossAxisExtentالعرض الأقصى للعنصر الواحد
itemCountعدد العناصر
itemBuilderيبني العنصر حسب الفهرس
✅ ما هي GridView.count؟

GridView.count هي أحد أنواع الـ GridView في Flutter، وهي تستخدم لإنشاء شبكة (Grid) من العناصر حيث نحدد عدد الأعمدة (columns) يدويًا باستخدام الخاصية crossAxisCount.

🧠 متى نستخدم GridView.count؟

تُستخدم عندما:

  • تريد شبكة عناصر (Cards، صور، مربعات…) موزعة بعدد ثابت من الأعمدة.
  • تعرف عدد الأعمدة مسبقًا، ولا تعتمد على حجم الشاشة.
  • تريد عرض عناصر قابلة للتمرير داخل شبكة بشكل منتظم.
🎯 الشكل العام (الصيغة الأساسية):
GridView.count(
  crossAxisCount: 2, // عدد الأعمدة
  crossAxisSpacing: 10, // المسافة الأفقية بين العناصر
  mainAxisSpacing: 10,  // المسافة العمودية بين العناصر
  childAspectRatio: 1,  // نسبة العرض إلى الارتفاع
  padding: EdgeInsets.all(8), // الهوامش داخل الشبكة
  children: [
    Container(color: Colors.red),
    Container(color: Colors.blue),
    Container(color: Colors.green),
    // المزيد من العناصر...
  ],
)
Dart
🧩 أهم الخصائص (Properties):
الخاصيةالنوعشرح الاستخدام
crossAxisCountintعدد الأعمدة في الشبكة
mainAxisSpacingdoubleالمسافة بين الصفوف (رأسيًا)
crossAxisSpacingdoubleالمسافة بين الأعمدة (أفقيًا)
childAspectRatiodoubleالنسبة بين العرض والارتفاع للعناصر. القيمة 1 تعني مربع. القيمة 2 تعني العرض ضعف الارتفاع.
paddingEdgeInsetsهوامش خارجية حول الشبكة
shrinkWrapboolهل تأخذ الشبكة فقط المساحة المطلوبة؟ تستخدم داخل أعمدة أو عناصر أخرى
physicsScrollPhysicsلتحديد نوع التمرير (مثل تعطيله أو جعله بسلاسة)
childrenList<Widget>العناصر المراد عرضها داخل الشبكة
🎥 مثال عملي بسيط:
GridView.count(
  crossAxisCount: 3,
  crossAxisSpacing: 8,
  mainAxisSpacing: 8,
  padding: EdgeInsets.all(10),
  childAspectRatio: 1,
  children: List.generate(12, (index) {
    return Container(
      color: Colors.teal,
      child: Center(
        child: Text(
          'عنصر ${index + 1}',
          style: TextStyle(color: Colors.white),
        ),
      ),
    );
  }),
)
Dart
🔍 الفرق بين GridView.count و GridView.builder؟
GridView.countGridView.builder
تصلح لقوائم صغيرة أو عدد معروف من العناصرتصلح لقوائم طويلة أو ديناميكية
تعتمد على children: []تعتمد على itemBuilder
أسهل وأسرع في الاستخدامأكثر كفاءة في الأداء عند القوائم الطويلة
🎯 حالات الاستخدام الشائعة:
  • عرض المنتجات في متجر إلكتروني.
  • عرض الصور في معرض.
  • عرض البطاقات التعليمية.
  • عرض خدمات أو ميزات التطبيق في واجهة منظمة.
⚠️ ملاحظات ونصائح:
  • إذا وضعتها داخل Column أو SingleChildScrollView، فعّل shrinkWrap: true حتى لا يحدث خطأ overflow.
  • لا تستخدم عدد كبير جدًا من العناصر داخل children: إذا كانت كثيرة، استخدم GridView.builder.