Pageview

🔹 ما هو PageView؟

  • ويدجت تسمح لك بالتنقل بين الصفحات أفقيًا (يمين/يسار) أو عموديًا (أعلى/أسفل).
  • مشابه لفكرة ListView لكن بدل التمرير المستمر → التمرير يكون صفحة بصفحة (Snap).
  • كثير يُستخدم في:
    • شاشات الترحيب (Onboarding)
    • السلايدر (Carousels)
    • التنقل بين تبويبات (مع BottomNavigationBar أو TabBar).
🔹 الأنواع
  1. PageView (العادي)
    تضع قائمة Widgets مباشرة. PageView( children: [ Container(color: Colors.red), Container(color: Colors.green), Container(color: Colors.blue), ], )
  2. PageView.builder
    ينشئ الصفحات عند الحاجة (موفر للذاكرة مثل ListView.builder). PageView.builder( itemCount: 5, itemBuilder: (context, index) { return Center( child: Text("الصفحة $index", style: TextStyle(fontSize: 24)), ); }, )
  3. PageView.custom
    نادر الاستخدام – يسمح بتحكم كامل في كيفية إنشاء الصفحات.
🔹 أهم الخصائص
1. children / itemBuilder
  • الصفحات نفسها (Widgets).
2. scrollDirection
  • اتجاه التمرير:
    • Axis.horizontal (افتراضي).
    • Axis.vertical.
3. controller
  • من نوع PageController:
    • يسمح بالتحكم اليدوي بالصفحات (goToPage, animateToPage).
    • معرفة الصفحة الحالية.

مثال:

PageController _controller = PageController(initialPage: 0);

PageView(
  controller: _controller,
  children: [...],
);
Dart
4. onPageChanged
  • Callback يُستدعى عند تغيير الصفحة. onPageChanged: (index) { print("الآن في الصفحة رقم $index"); },

5. physics

  • للتحكم بسلوك التمرير:
    • BouncingScrollPhysics() (ارتداد مثل iOS).
    • ClampingScrollPhysics() (توقف مثل Android).
    • NeverScrollableScrollPhysics() (تعطيل السحب – التنقل فقط بالـ controller).
6. pageSnapping
  • افتراضيًا: true → يتوقف التمرير دائمًا على صفحة كاملة.
  • لو جعلتها false → ممكن يقف في منتصف بين صفحتين (نادر الاستخدام).
🔹 مثال كامل مع التحكم
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final PageController _controller = PageController(initialPage: 0);
  int _currentPage = 0;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("PageView مثال")),
        body: Column(
          children: [
            Expanded(
              child: PageView(
                controller: _controller,
                onPageChanged: (index) {
                  setState(() {
                    _currentPage = index;
                  });
                },
                children: [
                  Container(color: Colors.red, child: Center(child: Text("صفحة 1"))),
                  Container(color: Colors.green, child: Center(child: Text("صفحة 2"))),
                  Container(color: Colors.blue, child: Center(child: Text("صفحة 3"))),
                ],
              ),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: List.generate(3, (index) {
                return Container(
                  margin: EdgeInsets.all(4),
                  width: 12,
                  height: 12,
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    color: _currentPage == index ? Colors.teal : Colors.grey,
                  ),
                );
              }),
            ),
            ElevatedButton(
              onPressed: () {
                _controller.nextPage(
                  duration: Duration(milliseconds: 500),
                  curve: Curves.ease,
                );
              },
              child: Text("التالي"),
            )
          ],
        ),
      ),
    );
  }
}
Dart
🔹 مميزات PageView
  • تنقل سلس (مع أنيميشن).
  • يوفر طريقة رائعة لشاشات Onboarding أو السلايدر.
  • يمكنك ربطه مع BottomNavigationBar أو Dots Indicator.
🔹 نصائح
  1. استخدم PageView.builder لو عندك عدد كبير من الصفحات.
  2. لو بدك تحكم يدوي → استخدم PageController.
  3. اربطه مع SmoothPageIndicator أو دوائر (Dots) ليوضح أي صفحة أنت فيها.
  4. لا تستخدمه بداخل ListView مباشرة إلا إذا كان ثابت الطول (لتجنب مشاكل Scroll).