مقدمة:
في هذا الدرس، سنستكشف مفهوم “Root Widget” في إطار عمل Flutter. يُعتبر الـ Root Widget نقطة البداية الأساسية في بنية تطبيقات Flutter، حيث يلعب دورًا حاسمًا في تنظيم وبناء واجهة المستخدم للتطبيق. سنتعرف على دور الـ Root Widget وأهميته في تطوير التطبيقات، بالإضافة إلى كيفية استخدامه بشكل صحيح لبناء تطبيقات Flutter قوية ومنظمة.
سنقوم أيضًا بعرض بعض الأمثلة العملية لاستخدام الـ Root Widget في تطبيقات Flutter، مما سيساعدنا في فهم كيفية بناء تطبيقات متطورة باستخدام هذا المفهوم الأساسي. بعد الانتهاء من هذا الدرس، ستكون قادرًا على تحديد واستخدام الـ Root Widget بفعالية في تطوير تطبيقات Flutter الخاصة بك.
في Flutter، يشير مصطلح “Root Widget” إلى العنصر الرئيسي في تطبيقك. هذا العنصر هو النقطة التي يبدأ منها بناء وتقديم واجهة المستخدم الخاصة بتطبيقك. يُمثل الـ Root Widget الجذرية نقطة البداية لشجرة العناصر (Widget tree)، والتي تتكون من مجموعة من العناصر (Widgets) التي تشكل واجهة التطبيق.
عادةً ما يكون الـ Root Widget هو عنصر من الأنواع التي تقدم واجهة مستخدم (UI) للمستخدم، مثل MaterialApp أو CupertinoApp في تطبيقات Flutter التقليدية. هذه العناصر تقدم الإطار الأساسي لتطبيقك وتتضمن الميزات الأساسية مثل إدارة المسارات (Routing)، وإعدادات الثيمات (Theming)، واللغة (Localization)، وغيرها من الخصائص التي تؤثر على كيفية عرض وتفاعل المستخدم مع التطبيق.
من الجدير بالذكر أنه يمكن استخدام أي عنصر في دور Root Widget طالما يتوافق مع احتياجات التطبيق. فمثلاً، يمكن استخدام عنصر Scaffold كـ Root Widget إذا كنت تريد تطبيق بسيط لا يتطلب إعدادات متقدمة مثل الإدارة المتقدمة للمسارات أو التثبيت العالمي للثيمات.
بشكل عام، يُعتبر تحديد الـ Root Widget وتحديده بشكل صحيح أحد الخطوات الأساسية في بناء تطبيق Flutter، حيث يُعتبر هذا العنصر الأساس لبنية التطبيق وتنظيمه.
مثال مع الشرح خطوة بخطوة
ها هو مثال بسيط يوضح كيفية استخدام عنصر MaterialApp كـ Root Widget في تطبيق Flutter:
خطوة 1: إنشاء مشروع Flutter جديد
نقم بإنشاء مشروع Flutter جديد باستخدام أحد محررات النصوص مثل Visual Studio Code أو Android Studio أو IntelliJ.
خطوة 2: تحرير ملف main.dart
نقم بتحرير ملف main.dart الذي يُعتبر نقطة البداية لتطبيقك.
خطوة 3: استيراد المكتبات اللازمة
استيراد مكتبة Flutter ومكتبة المواد التي سنستخدمها في هذا المثال:
import 'package:flutter/material.dart';
خطوة 4: تعريف الـ Root Widget
نقم بتعريف الـ Root Widget باستخدام عنصر MaterialApp واستخدمه كـ Root Widget.
يمكننا تحديد العديد من الخصائص في MaterialApp مثل العنوان والمسارات والثيمات وغيرها.
void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'My Flutter App', home: Scaffold( appBar: AppBar( title: Text('Welcome to My App'), ), body: Center( child: Text('Hello, Flutter!'), ), ), ); } }
في هذا المثال:
تم استخدام MaterialApp كـ Root Widget، وقد قمنا بتحديد عنوان التطبيق باستخدام الخاصية title.
استخدمنا Scaffold كعنصر فرعي داخل MaterialApp. Scaffold يوفر هيكلًا أساسيًا لتطبيقك بما في ذلك AppBar والـ Body.
أضفنا AppBar بعنوان ‘Welcome to My App’.
في Body، وضعنا عنصرًا مركزيًا (Center) يحتوي على عنصر نص (Text) يعرض “Hello, Flutter!”.
خطوة 5: تشغيل التطبيق
نقم بتشغيل التطبيق على محاكي الجهاز أو جهاز فعلي، وسترى التطبيق يعرض “Hello, Flutter!” في وسط الشاشة مع شريط عنوان يحمل عنوانًا مثل “Welcome to My App”.
هذا مثال بسيط يوضح كيفية استخدام MaterialApp كـ Root Widget في تطبيق Flutter وتوضيح الهيكل الأساسي للتطبيق.
شجرة التطبيق
شجرة التطبيق (Widget Tree) في Flutter تشبه بنية الشجرة حيث يكون لكل عنصر (Widget) والابناء الذين تحتويهم. يتم استخدام هذه الهيكلية لتنظيم عناصر التطبيق وتحديد ترتيبهم وتفاعلاتهم.
في المثال السابق، شجرة التطبيق تكون كالتالي:
MaterialApp │ └── Scaffold │ ├── AppBar │ │ │ └── Text ("Welcome to My App") │ └── Center │ └── Text ("Hello, Flutter!")
تبدأ الشجرة بعنصر MaterialApp الذي يعتبر الـ Root Widget في هذا المثال. ثم، يتم تحديد Scaffold كعنصر فرعي داخل MaterialApp. وبداخل Scaffold، يتم تحديد AppBar و Center كعناصر فرعية.
AppBar يحتوي على عنصر Text يعرض عنوان “Welcome to My App”.
Center يحتوي على عنصر Text يعرض “Hello, Flutter!” ويتم وضعه في المركز.
هذا الهيكل يعكس ترتيب وتنظيم عناصر التطبيق في Flutter. من السهل قراءة وفهم الشجرة هذه، مما يسهل على المطورين تحديد ترتيب وتفاعلات العناصر في التطبيق والقيام بالتعديلات عند الحاجة.
بالطبع، إليك كيفية إنشاء تطبيق بسيط باستخدام Root Widget في Flutter. سنقوم بإنشاء تطبيق يقوم بعرض نص بسيط على الشاشة.
خطوة 1: إنشاء مشروع Flutter جديد
نقم بإنشاء مشروع Flutter جديد. يمكنك استخدام أمر Flutter CLI لهذا الغرض كما يلي:
flutter create root_widget_app
خطوة 2: تحرير ملف main.dart
نفتح ملف main.dart الذي يقع في مجلد lib في مشروعك الجديد.
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Root Widget App', home: RootWidget(), ); } } class RootWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Root Widget Example'), ), body: Center( child: Text( 'Hello, Flutter!', style: TextStyle(fontSize: 24.0), ), ), ); } }
هنا قمنا بتعريف تطبيق Flutter بسيط. في main.dart، قمنا بإنشاء الكائن MyApp كـ StatelessWidget الذي يقوم بإرجاع MaterialApp كـ Root Widget، والذي يحتوي على Scaffold كـ Body.
خطوة 3: تشغيل التطبيق
نقم بتشغيل التطبيق على جهاز المحاكاة أو جهاز فعلي باستخدام الأمر التالي في مجلد المشروع:
flutter run
بهذه الطريقة، سيتم تشغيل التطبيق وسترى نافذة تطبيق Flutter تعرض “Hello, Flutter!” في وسط الشاشة مع شريط عنوان يحمل عنوانًا مثل “Root Widget Example”.
هذا هو تطبيق بسيط يستخدم Root Widget في Flutter. يُظهر كيف يمكنك استخدام MaterialApp كـ Root Widget وتضمين Scaffold كـ Body لتطبيق Flutter الأساسي.
شرح الكود :
سنوم بتقديم شرح لكل سطر في الكود وفقًا لما يلي:
import 'package:flutter/material.dart';
هذا السطر يقوم بإستيراد مكتبة Flutter المسؤولة عن بناء واجهات المستخدم وكل مكوناتها.
void main() { runApp(MyApp()); }
هذا السطر يعتبر نقطة البداية لتطبيق Flutter. تقوم الدالة main() بإستدعاء دالة runApp() والتي تأخذ كمعامل الـ Root Widget الذي سيتم عرضه في التطبيق، وهنا هو MyApp().
class MyApp extends StatelessWidget {
تعريف للكلاس MyApp الذي يمثل التطبيق. يتم تعيين MyApp كعنصر من نوع StatelessWidget لأن التطبيق لا يحتوي على حالة داخلية تتغير.
@override Widget build(BuildContext context) {
يُعدّ الدالة build() جزءًا من واجهة StatelessWidget، وهي الوظيفة التي يجب تنفيذها لتقديم الواجهة. يقوم build() بإعادة بناء واجهة المستخدم في كل مرة يتغير فيها الحالة.
return MaterialApp(
يتم هنا إنشاء عنصر MaterialApp، الذي يوفر هيكلًا لتطبيق Flutter، بما في ذلك إعدادات الثيمات وإدارة المسارات.
title: 'My Flutter App',
تحديد عنوان التطبيق.
home: Scaffold(
يُعدّ Scaffold عبارة عن عنصر يوفر تصميم وهيكلًا لتطبيقك، بما في ذلك AppBar و Body والعديد من المكونات الأخرى.
appBar: AppBar( title: Text('Welcome to My App'), ),
تعريف شريط العنوان (AppBar) لتطبيقك وتحديد عنوانه.
body: Center( child: Text('Hello, Flutter!'), ),
تحديد جسم التطبيق الذي يتم وسطه وإضافة عنصر نص (Text) يعرض “Hello, Flutter!”.
), );
إغلاق كافة العناصر الفرعية مثل Scaffold و MaterialApp، لضمان تناسق الهيكل والتركيب.
سنقوم بإنشاء تطبيق بسيط باستخدام MaterialApp كـ Root Widget. سنقوم بتحديد Scaffold كعنصر فرعي داخل MaterialApp، وسنضيف AppBar وعنصر Text داخله، ثم سنضيف عنصر Center لوضع العنصر النصي في المركز. لنقم بذلك خطوة بخطوة:
الخطوة 1: إنشاء ملف main.dart
نقم بإنشاء ملف جديد بعنوان main.dart في مشروعك.
الخطوة 2: استيراد المكتبات
نقم بجلب للمكتبات اللازمة، وهي Flutter و material.dart:
import 'package:flutter/material.dart';
الخطوة 3: تعريف الـ Root Widget
نعريف الـ Root Widget باستخدام MaterialApp واستخدمه كـ Root Widget:
void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter App', home: Scaffold( appBar: AppBar( title: Text('My First Flutter App'), ), body: Center( child: Text('Hello, Flutter!'), ), ), ); } }
الخطوة 4: تشغيل التطبيق
نقم بتشغيل التطبيق على المحاكي أو الجهاز الفعلي.
MaterialApp │ └── Scaffold │ ├── AppBar │ │ │ └── Text ("My First Flutter App") │ └── Center │ └── Text ("Hello, Flutter!")
هذه هي الخطوات الأساسية لإنشاء تطبيق Flutter بسيط باستخدام MaterialApp كـ Root Widget. تم تحديد AppBar و Center كعناصر فرعية داخل Scaffold لتحديد شريط العنوان ووضع العنصر النصي في المركز.
سنناقش تفاصيل الخطوات اللازمة لإنشاء مشروع تطبيق بسيط حول Flutter Root Widget.
سنقوم بإنشاء تطبيق يعرض نص بسيط مركزيًا في وسط الشاشة مع شريط عنوان.
الخطوة 1: إنشاء مشروع Flutter جديد
استخدم أمر Flutter الخاص بإنشاء مشروع جديد، يمكنك تنفيذ هذا الأمر في سطر الأوامر (Command Line) كما يلي:
flutter create root_widget_example
الخطوة 2: تعديل ملف main.dart
نفتح ملف main.dart في مشروعك الجديد واستبدل الكود بالتالي:
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Root Widget Example', home: Scaffold( appBar: AppBar( title: Text('Flutter Root Widget Example'), ), body: Center( child: Text( 'Welcome to Flutter Root Widget Example!', style: TextStyle(fontSize: 24.0), ), ), ), ); } }
الخطوة 3: تشغيل التطبيق
نقم بتشغيل التطبيق على المحاكي أو الجهاز الفعلي باستخدام الأمر التالي:
flutter run
شجرة الويدجت:
تشجير التطبيق سيكون كالتالي:
MaterialApp │ └── Scaffold │ ├── AppBar │ │ │ └── Text ("Flutter Root Widget Example") │ └── Center │ └── Text ("Welcome to Flutter Root Widget Example!")
نقم بتشغيل التطبيق وسنرى عنصر نصي وسط الشاشة مع شريط عنوان يحمل العنوان المحدد. هذا يعرض كيفية استخدام MaterialApp كـ Root Widget في تطبيق Flutter البسيط.
لنقم بإنشاء مشروع أكثر تقدماً يستخدم Root Widget بشكل متقدم. سنقوم بإنشاء تطبيق يستخدم MaterialApp كـ Root Widget، ونضيف عدة شاشات ونقوم بتنقل بينها باستخدام إدارة المسارات (Routing) باستخدام Navigator.
الخطوة 1: إنشاء مشروع Flutter جديد
استخدم الأمر التالي لإنشاء مشروع جديد:
flutter create advanced_root_widget_example
الخطوة 2: تعديل ملف main.dart
قم بتحرير ملف main.dart كما يلي:
import 'package:flutter/material.dart'; import 'package:advanced_root_widget_example/screens/home_screen.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Advanced Root Widget Example', theme: ThemeData( primarySwatch: Colors.blue, ), home: HomeScreen(), ); } }
الخطوة 3: إنشاء الشاشات
أنشئ ملف جديد بعنوان home_screen.dart داخل مجلد screens، وضع الكود التالي:
import 'package:flutter/material.dart'; import 'package:advanced_root_widget_example/screens/second_screen.dart'; class HomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Home Screen'), ), body: Center( child: ElevatedButton( onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => SecondScreen()), ); }, child: Text('Go to Second Screen'), ), ), ); } }
ثم، ننشئ ملفًا جديدًا بعنوان second_screen.dart داخل مجلد screens وضع الكود التالي:
import 'package:flutter/material.dart'; class SecondScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Second Screen'), ), body: Center( child: ElevatedButton( onPressed: () { Navigator.pop(context); }, child: Text('Go back to Home Screen'), ), ), ); } }
الخطوة 4: تشغيل التطبيق
قم بتشغيل التطبيق باستخدام الأمر التالي:
flutter run
شجرة الويدجت:
MaterialApp │ └── HomeScreen │ ├── Scaffold │ │ │ ├── AppBar │ │ │ │ │ └── Text ("Home Screen") │ │ │ └── Center │ │ │ └── ElevatedButton │ │ │ └── Text ("Go to Second Screen") │ └── SecondScreen │ ├── Scaffold │ │ │ ├── AppBar │ │ │ │ │ └── Text ("Second Screen") │ │ │ └── Center │ │ │ └── ElevatedButton │ │ │ └── Text ("Go back to Home Screen")
هذا المشروع يعرض كيفية استخدام MaterialApp كـ Root Widget في تطبيق Flutter متقدم يستخدم إدارة المسارات للتنقل بين الشاشات.
سنقوم بإنشاء تطبيق كويز بسيط حول مفهوم Root Widget في Flutter. سيقوم التطبيق بعرض سؤال متعلق بالموضوع واختيارات متعددة الاختيارات، وعرض نتيجة الاختبار بناءً على الإجابة الصحيحة. سنستخدم MaterialApp كـ Root Widget وسنستخدم عدة عناصر ويدجت لبناء واجهة المستخدم.
نقوم بتصميم تطبيق بسيط لعرض اختبار (Quiz) عن Root Widget في Flutter. سنقوم بعرض سؤال متعلق بمفهوم Root Widget واختيارات متعددة الاختيارات، مع إمكانية اختيار الإجابة الصحيحة.
الخطوة 1: تحضير الأسئلة
لنقم بتحضير مجموعة بسيطة من الأسئلة حول مفهوم Root Widget. هنا سؤال مثالي:
سؤال: ما هو دور Root Widget في تطبيق Flutter؟
أ- يمثل نقطة البداية لتنظيم بنية التطبيق وبناء واجهة المستخدم.
ب- هو عنصر واجهة المستخدم الرئيسي الذي يتفاعل مباشرة مع المستخدم.
ج- يستخدم لتحديد الثيمات والألوان في التطبيق.
د- لا يوجد دور محدد لـ Root Widget في Flutter.
الخطوة 2: تنفيذ التطبيق
سنقوم بتنفيذ التطبيق باستخدام Flutter ونضيف السؤال الذي أعددناه.
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Quiz App', home: Scaffold( appBar: AppBar( title: Text('Root Widget Quiz'), ), body: QuizScreen(), ), ); } } class QuizScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'سؤال: ما هو دور Root Widget في تطبيق Flutter؟', textAlign: TextAlign.center, style: TextStyle(fontSize: 18.0), ), SizedBox(height: 20.0), RaisedButton( onPressed: () { // Add logic to handle 's answer }, child: Text('أ- يمثل نقطة البداية لتنظيم بنية التطبيق وبناء واجهة المستخدم.'), ), RaisedButton( onPressed: () { // Add logic to handle 's answer }, child: Text('ب- هو عنصر واجهة المستخدم الرئيسي الذي يتفاعل مباشرة مع المستخدم.'), ), RaisedButton( onPressed: () { // Add logic to handle 's answer }, child: Text('ج- يستخدم لتحديد الثيمات والألوان في التطبيق.'), ), RaisedButton( onPressed: () { // Add logic to handle 's answer }, child: Text('د- لا يوجد دور محدد لـ Root Widget في Flutter.'), ), ], ), ); } }
الخطوة 3: إضافة منطق لمعالجة الإجابات
نحتاج إلى إضافة منطق لمعالجة اختيارات المستخدم والتحقق من صحة الإجابة.
يمكننا استخدام مثلاً Snackbar لإظهار رسالة توضح ما إذا كانت الإجابة صحيحة أو خاطئة.
void checkAnswer(BuildContext context, bool isCorrect) { String message = isCorrect ? 'إجابة صحيحة!' : 'إجابة خاطئة!'; Scaffold.of(context).showSnackBar(SnackBar( content: Text(message), duration: Duration(seconds: 2), )); }
الخطوة 4: ربط الإجابات بالمنطق
الآن نحتاج فقط لربط الأزرار بالمنطق لمعالجة الإجابات. في مثالنا، سنقوم بتحديد الإجابة “أ” كالإجابة الصحيحة.
RaisedButton( onPressed: () { checkAnswer(context, true); // true for correct answer }, child: Text('أ- يمثل نقطة البداية لتنظيم بنية التطبيق وبناء واجهة المستخدم.'), ),
وبهذا نكون قد أنشأنا تطبيق كويز بسيط حول مفهوم Root Widget في Flutter.
الكود النهائي
الكود النهائي لتطبيق الكويز حول مفهوم Root Widget في Flutter:
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Quiz App', home: Scaffold( appBar: AppBar( title: Text('Root Widget Quiz'), ), body: QuizScreen(), ), ); } } class QuizScreen extends StatelessWidget { void checkAnswer(BuildContext context, bool isCorrect) { String message = isCorrect ? 'إجابة صحيحة!' : 'إجابة خاطئة!'; Scaffold.of(context).showSnackBar(SnackBar( content: Text(message), duration: Duration(seconds: 2), )); } @override Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'سؤال: ما هو دور Root Widget في تطبيق Flutter؟', textAlign: TextAlign.center, style: TextStyle(fontSize: 18.0), ), SizedBox(height: 20.0), RaisedButton( onPressed: () { checkAnswer(context, true); // true for correct answer }, child: Text('أ- يمثل نقطة البداية لتنظيم بنية التطبيق وبناء واجهة المستخدم.'), ), RaisedButton( onPressed: () { checkAnswer(context, false); }, child: Text('ب- هو عنصر واجهة المستخدم الرئيسي الذي يتفاعل مباشرة مع المستخدم.'), ), RaisedButton( onPressed: () { checkAnswer(context, false); }, child: Text('ج- يستخدم لتحديد الثيمات والألوان في التطبيق.'), ), RaisedButton( onPressed: () { checkAnswer(context, false); }, child: Text('د- لا يوجد دور محدد لـ Root Widget في Flutter.'), ), ], ), ); } }
نقم بتشغيل التطبيق وستظهر لك الشاشة الرئيسية للكويز، حيث يتم عرض السؤال والخيارات، وعند النقر على أحد الخيارات ستظهر رسالة توضح ما إذا كانت الإجابة صحيحة أو خاطئة.
اختبار بسيط حول مفهوم Root Widget في Flutter. يحتوي الاختبار على سؤال واحد مع أربعة خيارات متعددة الاختيارات.
الخيارات:
أ- يمثل نقطة البداية لتنظيم بنية التطبيق وبناء واجهة المستخدم.
ب- هو عنصر واجهة المستخدم الرئيسي الذي يتفاعل مباشرة مع المستخدم.
ج- يستخدم لتحديد الثيمات والألوان في التطبيق.
د- لا يوجد دور محدد لـ Root Widget في Flutter.
الإجابة الصحيحة:
أ- يمثل نقطة البداية لتنظيم بنية التطبيق وبناء واجهة المستخدم.
الخيارات:
أ- يحدد اللون الرئيسي للتطبيق.
ب- يحدد النص الافتراضي لكل النصوص في التطبيق.
ج- يشكل النقطة الأساسية لبنية التطبيق وتنظيم عناصر واجهة المستخدم.
د- يدير حركة الملاحة بين صفحات التطبيق.
الخيارات:
أ- MaterialApp و CupertinoApp فقط.
ب- Scaffold و Container فقط.
ج- أي عنصر يعتبر واجهة المستخدم الرئيسية في التطبيق.
د- StatelessWidget و StatefulWidget فقط.
الخيارات:
أ- MaterialApp
ب- Scaffold
ج- Center
د- Container
الخيارات:
أ- لا يوجد تأثير.
ب- يمكن أن يؤدي إلى تعطل التطبيق.
ج- يمكن أن يؤثر على شكل وسلوك التطبيق بشكل كامل.
د- يمكن أن يؤدي إلى تغيير الألوان والمظهر العام للتطبيق.
الإجابات:
ج- يشكل النقطة الأساسية لبنية التطبيق وتنظيم عناصر واجهة المستخدم.
ج- أي عنصر يعتبر واجهة المستخدم الرئيسية في التطبيق.
أ- MaterialApp
ج- يمكن أن يؤثر على شكل وسلوك التطبيق بشكل كامل.
أتمنى أن تكون هذه الأسئلة مفيدة لك.