كيف تنقل بين الصفحات في Flutter بكل سهولة؟
التنقل وتوجيه الصفحات في Flutter
يعد التنقل بين الصفحات عنصراً أساسياً في أي تطبيق. في Flutter، هناك عدة طرق للتنقل بين الشاشات، بدءاً من الأساليب البسيطة وصولاً إلى الحلول المتقدمة. في هذا الدرس، سنتعرف على كيفية تنفيذ التنقل في تطبيقات Flutter بطريقة فعالة ومنظمة.
في هذا الدرس سنتعلم:
- التنقل الأساسي باستخدام Navigator
- التنقل المسمى وكيفية تنظيم المسارات
- استخدام مكتبة GoRouter للتنقل المتقدم
- تخصيص الرسوم المتحركة للتنقل
- أفضل الممارسات في تنفيذ نظام التنقل
التنقل الأساسي
يوفر Flutter نظام تنقل يسمى Navigator، يعمل بمبدأ المكدس (Stack). عندما تنتقل إلى صفحة جديدة، يتم وضعها فوق الصفحة الحالية في المكدس. وعند العودة، يتم إزالة الصفحة العلوية من المكدس. دعونا نتعرف على الطرق الأساسية للتنقل:
// الانتقال إلى صفحة جديدة
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondPage(),
),
);
// العودة إلى الصفحة السابقة
Navigator.pop(context);
// استبدال الصفحة الحالية
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => NewPage(),
),
);
في المثال السابق:
Navigator.push
: يضيف صفحة جديدة فوق الصفحة الحاليةNavigator.pop
: يزيل الصفحة الحالية ويعود للصفحة السابقةNavigator.pushReplacement
: يستبدل الصفحة الحالية بصفحة جديدة
التنقل المسمى
التنقل المسمى هو طريقة أكثر تنظيماً لإدارة المسارات في تطبيقك. بدلاً من إنشاء الصفحات مباشرة، يمكنك تعريف مسارات مسماة وربطها بالصفحات. هذا يجعل التنقل أكثر مرونة وأسهل في الصيانة.
// تعريف المسارات في MaterialApp
MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => HomePage(),
'/second': (context) => SecondPage(),
'/profile': (context) => ProfilePage(),
},
);
// الانتقال باستخدام المسارات المسماة
Navigator.pushNamed(
context,
'/second',
);
// تمرير معلمات مع التنقل
Navigator.pushNamed(
context,
'/profile',
arguments: {'userId': '123'},
);
مميزات التنقل المسمى:
- تنظيم أفضل للمسارات في مكان واحد
- سهولة تغيير الصفحات المرتبطة بالمسارات
- إمكانية تمرير معلمات بين الصفحات
استخدام GoRouter
GoRouter هو مكتبة متقدمة للتنقل في Flutter، تقدم العديد من الميزات المتقدمة مثل المسارات المتداخلة والتنقل المستند إلى URL. لاستخدام GoRouter، أضف التبعية التالية إلى ملف pubspec.yaml:
dependencies:
go_router: ^10.1.0
مثال على استخدام GoRouter:
import 'package:go_router/go_router.dart';
// تعريف المسارات
final router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => HomePage(),
routes: [
// مسارات متداخلة
GoRoute(
path: 'profile',
builder: (context, state) => ProfilePage(),
),
GoRoute(
path: 'settings',
builder: (context, state) => SettingsPage(),
),
GoRoute(
path: 'products/:id', // مسار مع معلمة
builder: (context, state) {
final productId = state.pathParameters['id']!;
return ProductDetailsPage(id: productId);
},
),
],
),
],
// معالجة الأخطاء
errorBuilder: (context, state) => ErrorPage(),
);
// استخدام GoRouter في MaterialApp
MaterialApp.router(
routerConfig: router,
title: 'مثال GoRouter',
theme: ThemeData(
primarySwatch: Colors.blue,
),
);
// التنقل باستخدام GoRouter
context.go('/profile');
context.push('/products/123');
مميزات GoRouter:
- المسارات المتداخلة: تنظيم المسارات بشكل هرمي
- معلمات المسار: تمرير واستقبال المعلمات بسهولة
- معالجة الأخطاء: عرض صفحة خطأ مخصصة للمسارات غير الموجودة
- التنقل المستند إلى URL: مفيد للتطبيقات التي تعمل على الويب
- التوجيه التلقائي: إعادة التوجيه بناءً على حالة التطبيق
الرسوم المتحركة في التنقل
يمكنك تخصيص تأثيرات الانتقال بين الصفحات لتحسين تجربة المستخدم. Flutter يوفر عدة خيارات للرسوم المتحركة:
// تأثير الانتقال المخصص
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => NewPage(),
transitionDuration: Duration(milliseconds: 500),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
// تأثير التلاشي
return FadeTransition(
opacity: animation,
child: child,
);
// أو تأثير الانزلاق
return SlideTransition(
position: Tween(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(animation),
child: child,
);
// أو تأثير التكبير
return ScaleTransition(
scale: animation,
child: child,
);
},
),
);
حفظ حالة الصفحة
في بعض الحالات، قد تحتاج إلى حفظ حالة الصفحة عند التنقل. على سبيل المثال، حفظ موقع التمرير في قائمة طويلة:
// استخدام PageStorageKey لحفظ موقع التمرير
class ListPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
key: PageStorageKey('myListView'),
itemCount: 100,
itemBuilder: (context, index) => ListTile(
title: Text('عنصر $index'),
),
),
);
}
}
// حفظ وإعادة تحميل حالة الصفحة
class StatefulPage extends StatefulWidget {
@override
_StatefulPageState createState() => _StatefulPageState();
}
class _StatefulPageState extends State with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true; // حفظ الحالة عند التنقل
@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
// محتوى الصفحة
);
}
}
أفضل الممارسات
عند تنفيذ نظام التنقل في تطبيقك، اتبع هذه الممارسات للحصول على تجربة مستخدم مثالية وكود قابل للصيانة:
- تنظيم المسارات: احتفظ بتعريفات المسارات في ملف منفصل للتطبيقات الكبيرة
- معالجة الأخطاء: دائماً قم بتوفير صفحة خطأ 404 للمسارات غير الموجودة
- حماية المسارات: تحقق من صلاحيات المستخدم قبل السماح بالوصول للصفحات المحمية
- الأداء: تجنب تكديس الكثير من الصفحات في الذاكرة
- تجربة المستخدم: استخدم الرسوم المتحركة بشكل معتدل لتحسين تجربة المستخدم
- التوثيق: وثق نظام التنقل وهيكل المسارات في التطبيق
الخاتمة
التنقل هو جزء أساسي من أي تطبيق Flutter، ويؤثر بشكل مباشر على تجربة المستخدم. في هذا الدرس، تعلمنا كيفية تنفيذ أنظمة تنقل مختلفة بدءاً من الأساسيات وصولاً إلى الحلول المتقدمة باستخدام GoRouter. تذكر دائماً أن اختيار نظام التنقل المناسب يعتمد على حجم تطبيقك ومتطلباته.
مشروع تطبيقي:
- قم بإنشاء تطبيق بسيط يحتوي على ثلاث صفحات: الرئيسية، الملف الشخصي، والإعدادات
- نفذ التنقل بين الصفحات باستخدام الطريقة الأساسية أولاً
- قم بتحويل التطبيق لاستخدام التنقل المسمى
- أخيراً، استخدم GoRouter وأضف بعض المميزات المتقدمة مثل حماية المسارات
اترك تعليقاً