Professional Documents
Culture Documents
lowercase with( اسم المشروع ال يحتوي على مسافات وال أحرف كبيرة ويمكن أن يحتوي على
)underscores
:أنواع المتغيرات الرقمية
int , double , num
int , double عبارة عن األب لكل منnum
:Example
;int x = 5
double y = 7.2; ًيقبل أرقام صحيحة أيضا
;num number1 = 5
print(number1.runtimeType); int لطباعة نوع المتغير وهنا هو
;num number2 = 2.2
print(number2.runtimeType); double لطباعة نوع المتغير وهنا هو
String المتغير النصي هو
:Example
String name = "Noor";
print(name.length); اليجاد\ طول النص
print(name.toLowerCase()); لتحويل النص ألحرف صغيرة
print(name.toUpperCase()); لتحويل النص ألحرف كبيرة
ثانياً :var \:يقبل جميع القيم ( أرقام صحيحة أرقام عشرية ونصوص) للمرة األولى فقط عند
التعريف وال يمكن تغيير النوع مرة اخرى ولكن يمكن تغيير القيمة
:Example
;"var x = "Noor
;x = 5 يمكن تغيير القيمة فقط) ) هكذا خطأ ألن المتغير تم تعريفه كنص وال يمكن تغييره
لرقم
هكذا صحيح ألننا غيرنا القيمة من نص الى نص اخر ;"x = "ahmed
باختصار ال varعند تعريفه ألول مرة يمكن وضع ما نشاء فيه ( نصوص أو أرقام أو أرقام عشرية)
ولكن بعد ذلك ال يمكننا تغيير النوع بمعنى اذا كنا عرفنا المتغير كرقم ال يمكن تحويله لنص واذا
كان نص ال يمكن تحويله لرقم
المسموح فقط تغيير القمية بمعنى يمكن تغيير القيم من نص لنص اخر أو من رقم لرقم اخر
3
: if دالة
int number = 12;
if (number % 2 == 0) {
print("Even");
} else {
print("Odd");
}
كما نالحظ ال يوجد تغيير عليها نفس لغات البرمجة\ األخرىifدالة ال
:for loop
\:الطريقة األولى وهي المعتادة
for (var i = 0; i < 5; i++) {
print("Hello world");
}
\:الطريقة الثانية
;List<int> numbers = [ 1 , 2 , 3 , 4 , 5]
for (int num in numbers) {
print(num);
}
:foreach الطريقة الثالثة وهي
{ numbers.forEach((element)
;print(element)
;)}
4
هنا اذا كان ل xقيمة تبقى كما هي أما اذا كانت nullنجعل قيمتها x ??= 8; 8
Lists in dart:
;]List list = [true , "noor " , 5 , 3.2 , false
;]List<dynamic> list = [true , "noor " , 5 , 3.2
ما بين األقواس < >dynamicيسمى generic type
الحالتان نفس المعنى سواء وضعنا dynamicأم لم نضع كالهما نفس الحالة\
لست تقبل جميع القيم بشكل افتراضي تكون من نوع dynamic
لست من نوع سترنج ;]" List<String> list = ["noor " , "ahmed " , "abood
لست من نوع أرقام صحيحة ;]List<int> list = [27 , 1 , 2003
لست من نوع أرقام عشرية ;]List<double> list = [1.3 , 2.4 ,7.9
) -> trueلفحص اذا كانت تحتوي على عناصر أم ال( elements.isNotEmpty
) -> ("ahmed" , "noor" , true , 4.2 ,لطباعتها بشكل معكوس( elements.reversed
;)"nader" , 1
ال تؤثر على اللست األصلية وإنما مجرد طباعة ( تبقى اللست األصلية كما هي (بس طباعة))
اذا أردنا أن حول من list Stringإلى list intمثال لدينا listبها مجموعة\ اسماء ونريد أن نستخدمها\
لعمل ليست أخرى تحتوي على عدد أحرف كل اسم من االسماء نستخدم دالة ( mapدالة
mapوليست )Mapهي دالة وليس نوع تخزين
الفرق بين دالة الماب و foreachأن ال foreachال ترجع داتا أما الماب بترجع داتا من نوع Itreable
عبارة عن األب لكل داتا قابلة لعمل loopعليها مثل Itreable:Map , List
Sets in dart:
ال setفي دارت ال تقبل التكرار ولكن ال يحدث ايرور عند التكرار ولكن يتم تجاهل العنصر المكرر
كأنه غير موجود
:Enum in dart
يستخدم لتعريف مجموعة قيم ثابتة مثل أيام األسبوع أو مثال األشهر أو فصول السنة Enum:
وهكذا
يفضل تسميته بالبدء بحرف كبير والقيم الخاصة به بحرف صغير ويتم تعريفه خارج المين ويشبه
تعريف الكالس
ال يمكن تعريف أرقام بداخله فقط كلمات
} enum Seasons { winter, spring, summer, autumn
{ )(void main
; Seasons first = Seasons.autumn
اليجاد اسم العنصر print(first.name); //
اليجاد موقع العنصر علما بأن العد يبدأ من صفر print(first.index); //
اليجاد\ نوع العنصر وفي هذه الحالة\ يكون print(first.runtimeType); //Seasons
}
:Functions in dart
{ )(void printHello
;)" print("Hello
}
دالة voidتقوم بطباعة Helloعند استداعاءها\ في ال mainال توضع داخل جملة طباعة ألنها من
نوع void
هكذا يتم استدعاءها ;)(printHello
نستخدمها في حالة كانت ال functionبها سطر واحد (طريقة مختصرة) Another way:
;int sum(int x , int y) => return x + y
دالة intتقوم بجمع عددين\ عند استداعاءها في ال mainتوضع داخل جملة طباعة\ ألنها من نوع
int
;))print(sum(7 , 8 هكذا يتم استدعاءها\
هنا مررنا القيم األولى ولم نمرر األخرى الن المدخالت اختيارية ;)info(15
مالحظة مهمة جدا :ال نستطيع أن نعطي قيمة للعنصر التاني قبل أن نعطي لألول يجب أن نلتزم
بالترتيب\
هكذا ايرور ألننا أعطينا قيم للمتغير الثاني Stringولم نعطي قيمة للمتغير األول ;)"info("ahmed
11
هي مدخالت\ اختيارية االدخال وغير اجبارية التمرير يتم اعطاء المتغير قيمة عن طريق\ اسم
المتغير
يتم وضعهم داخل {} ويجب أن نعطيهم قيم افتراضية أو نستخدم كلمة required
الهدف من وضع قيمة افتراضية\ أو requiredهو الحماية من ال nullعندما نستخدم كلمة
requiredيصبح المتغير اجباري التمرير
هنا مررنا القيم األولى ولم نمرر األخرى الن المدخالت اختيارية ;)info(age: 22
هكذا ايضا صحيح ألننا غير مجبرين\ بالترتيب\ وانما نمرر القيمة عن ;)"info("address" : "Gaza
طريق االسم
مالحظة :يمكن الدمج بين النوع االجباري واالختياري في نفس funtionوال يمكن الدمج بين
نوعين االختياري ( ) optional positional , optional named
}{ )}"" = void info(String name = "" , {int age = 0 , String address
هكذا ال nameاجباري التمرير\ و ال ageو ال addressاختياريين
void main() {
String fullName = "omar ahmed ali";
String formatedName = formatFullName(fullName, capetalizeName);
ومررنا لها مدخالن األول سترنج والثانيformatedFullName function هنا قمنا باستدعاء
function capetalizedName
print(formatedName);
}
OOP in Dart:
class Student{
String? name ;
int? age;
أو نعطيهم قيم افتراضيةnullإما نجعلهم يقبلو ال
String name = "" ;
int age = 0;
}
13
ال يحدث ايرورnew ولو كتبناnew \مالحظة عند استدعاء الكالس داخل المين لسنا بحالة\ لكتابة
) اختيارية ووجودها\ من عدمه ال يؤثرnew الطريقتان صحيحتان (كلمة
العادي ويكون اسمه مثل اسم الكالس وال يمكن انشاء اكثر من واحد منconstructorوهو ال
)هذا النوع (فقط واحد
class Student{
String? name ;
int? age;
double? gpa
2. named constructor:
ويمكن انشاءAnyname. شبه العادي ويكون اسمه مثل اسم الكالس ثمconstructorوهو ال
اكثر من واحد من هذا النوع
Student.one
Student.cons
Student.a
Student.abc
. يمكننا كتابة أي اسم بعد
Student.first (String? name , int? age , double? gpa){
this.name = name;
this.age = age;
this.gpa = gpa;
}
14
Inheritance:
class Car{
String? name;
Car(String? name){
this.name = name;
}
}
به مدخالت يجب تمرير\ هذه المدخالتconstructor \ من كالس وكان لديهextends عند عمل
superبواسطة كالس االبن عن طريق
class Skoda extends Car{
Skoda( String name ) : super (name);
}
abstract Class:
abstract فيجب أن يكونabstract اذا كان الكالس يحتوي على دالة من نوع
abstract فليس ضروريا أن يحتوي على دالة من نوعabstract أما اذا كان الكالس
abstract لكل الدوال التي من نوعoverride يجب عملabstract عند الوراثة من كالس من نوع
والباقيabstract لجميع الدوال (االجباري فقط التي من نوعoverride وليس شرطا أن يتم عمل
)اختياري
class Bmw extends Car {
@override
String getBrandName() {
return "Bmw";
}
@override
int numOfWheels() {
return 4;
}
}
15
) او الoverride (لدينا\ حرية\ بعملabstract ألنها ليستmodel لدالةoverride هنا لم نقم بعمل
:implements in Dart
لجميع متغيراتoverride من كالس يجيب عملimplements عند عمل:مالحظة مهمة جدا جدا
أم الabstract ودوال الكالس سواء كانت من نوع
String getBrandName();
int numOfWheels();
String model() {
return "2022";
}
}
@override
int numOfWheels() {
return 4;
}
@override
String name = "Bmw 2022";
@override
String model() {
return "model 2022";
}
}
لكل محتوياتoverride وجب علينا أن نقوم بعملimplements نالحظ أنه عندما قمنا بعمل
الكالس األب
:Mixins in Dart
من االضافات\ المميزة في لغة دارت والهدف منها أنه ال يمكننا عمل extendsمن أكثر من كالس
وفي نفس الوقت يمكننا عمل implementsألكثر من كالس ولكننا مجبرين لعمل override
لجميع دوال ومدخالت كل كالس والعمليتان ( )extend , implementsليست كافيات ألن لكل
واحدة منها عيب ونحن بحاجة\ لحل فجاءت mixinsلهذا السبب
بعد اسم الكالس نكتب withثم اسماء الكالسات المراد عمل وراثة منها
{ class Car
; String? name
; int? numOfWheels
{)int calculateSpeed(int speed
;return speed * 100
}
}
{class Machine
;int? motorPower
}
{)(void main
;)(Bmw bmw = Bmw
;bmw.motorPower = 5
من خالل األوبجكت الذي انشأناه نستطيع الوصول لجميع الدوال والمتغيرات بين الكالس وذلك
بفضل mixins
}
مالحظة مهمة جدا جدا :الكالس الذي نريد\ الوصول اليه من خالل withالخاصة ب mixins
ال يمكن أن يحتوي على constructorاذا كان يحتوي على constructorيحدث ايرور
من اختصارات دارت أننا نستطيع الوصول للمتغير بعد انشاء األوبجكت مباشرة\ بطريقة مختصرة
المتغير constمتغير ال تتغير قيمته وجيب اعطاءه قيمة عن التعريف وال يمكن تغيير القيمة الحقا
وال يمكن أن يقبل الnull
;final int y
المتغير finalمتغير ال تتغير قيمته ويمكن اعطاءه قيمة مباشرة\ عند التعريف أو من خالل
constructorوال يمكن أن يقبل ال nullوال يمكن تغيير القيمة الحقا
مالحظة مهمة بخصوص : staticيتم استدعاء من خالل اسم الكالس فقط ال يمكن استدعاءه
بعد تعريف األوبجكت ( فقط من اسم الكالس)
;test.z = 8
;)(Test t = Test
هكذا ايرور ألن المتغير من نوعstaticيتم استدعاءه\ من اسم الكالس فقط ;t.z = 10
:Introduction to Flutter
لكي نقوم بعمل runلتطبيق فالتر\ نستخدم دالة الrunApp
{ )(void main
MyAppهو الويدجت\ التي سنقوم بعمل runلها ;))(runApp(const MyApp
}
فمثال )(Textبها متغير اجباري وهو Stringوبها عدة متغيرات اختيارية مثل styleوغيرها\
عبارة عن الويدجت الرئيسية لتطبيق فالتر\ وال يمكن أن نقوم بعمل رن للتطبيق Material App:
وهي غير موجودة وتوجد\ مرة واحدة داخل التطبيق
هناك نوعين رئيسين من الويدجت في فالتر وهما Stateless Widgetواالخر Stateful Widget
كالهما عبارة عن abstract classيرث من الكالس األب لهما وهو Widget
وبما أنها abstractفيجب علينا عند عمل extendsمنهم يجب علينا أن نقوم بعمل override
لدالة buildالتي هي داخلهما ومن\ نوع abstract
لكي نظهر شاشة بيضاء للبدء\ بوضع المحتوى عليها كما في برنامج الرسام الكوجود على ويندوز\
نستخدم ال Widgetالتي اسمها Scaffoldويتم وضعها داخل ال homeوالمقصود بال homeهي
الشاشة نفسها بمعنى أن الشاشة تحتوي على Scaffold
لكي نزيل العالمة\ الحمراء الموجودة في اعلى يمين الشاشة نستخدم هذا الكود
debugShowCheckedModeBanner: false,
المختصر إلى حد االن أن كل شيء عبارة Widgetو هناك نوعان رئيسان من Widgetsوهما
Statelessو Statefulوهما من نوع abstractوبها دالة buildيجب عمل overrideلها والتطبيق
يجب أن يحتوي على ال MaterialAppمرة واحد فقط وبدونها يظهر لنا exceptionعند الرن وهي
تقوم بحساب أبعاد الشاشة المراد تشغيل التطبيق عليها وكل واجهة بالتطبيق\ لها Scaffold
خاص بها يتم وضعه داخل ال homeوهو الشاشة البيضاء\ التي يتم وضع العناصر عليها والزالة
العالمة\ الحمراء في أعلى يمين الشاشة نستخدم debugShowCheckedModeBanner: false
ونضعه داخل MaterialApp
22
مالحظة يتم تقسيم الشاشة في تطبيق إلى ثالث أقسام وهي AppBarو bodyو bottom
navigation bar
AppBar
Body
لوضع نص في منتصف أي مساحة نستخدم Centerولها مدخل\ يمسى childيتم وضع النص من
خالله
لكي نقوم بوضع ال appBarفي أعلى الشاشة نستخدم ال Widgetالتي اسمها AppBar
وال يهم الترتيب بين ال appBarو ال bodyو الbottomNavigationBar
24
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text("HOME"),
),
body: Column(
children: [
Row(
children: [
Text("name: "),
Text(map["name"]),
],
),
Row(
children: [
Text("age: "),
Text(map["age"].toString()),
],
),
Row(
children: [
Text("isMale"),
Text(map["isMale"] ? "Male" : "Female"),
],
),
Row(
children: [
Text("University"),
Text(map["University"]),
],
),
],
),
),
);
}
}
27
اذا كنا نضيف اضافة صورة من الجهاز (صورة موجودة مسبقا لدينا) يتم تفعيل ال assetsفي ملف
( pubspec.yamlلغة yamlهي لغة تعتمد على مبدأ االزاحات (المساطر))
يكون الناتج هكذا مساحة ال Container 200 * 200والخلفية سوداء وبداخله Columnبه نصان
يوجد لل Columnو Rowخواص كثيرة أهمها ال Alignmentوتكون على قسمين:
وهو المحور الرئيسي mainAxisAlignment
31
مالحظة:
بشكل افتراضي يأخذ ال Columnحجم الشاشة عموديا ويأخذ حجم أكبر عنصر فيه افقيا
وال Rowياخذ حجم الشاشة عرضيا ويأخذ\ حجم أطول عنصر فيه عموديا
اذا اردنا إعطاء ال Columnكامل الحجم أفقيا نكتب width: double.infinity
اذا اردنا إعطاء ال Rowكامل الحجم عمويا نكتب height: double.infinity
هنا أردنا أن نعمل فاصل\ ما بين عنصرين\ مثال لدينا\ نص ثم صورة ثم نص ونريد\ عمل فاصل بينهم\:
32
في حال كان لدينا Columnوكان لدينا عناصر ال يكفي عرضها في الشاشة سيظهر لنا كالتالي:
33
هناك حل اخر لمشكلة أن حجم الشاشة ال يكفي لما نحتاج لعرضه الطريقة األولى هي
SingleChildScrollViewوالثانية هي باستخدام listview
واستخدام ال listviewأفضل للتطبيق من استخدام SingleChildScrollView
التكملة في صفحة <<<<35
35
}
listview هي الواجهة الموجود\ بها الBuildContext context
ويبدأ من صفرlistview هو ترقيم لمواقع العناصر في الint index
وهي ويدجت جاهزة منListTile هيreturn التي قمنا بإرجاعها\ فيwidgetفي المثال ال
flutter
ListTile Widget
itemCount: 5 عناصر كما هو موضح في5 هو عدد العناصر المراد عرضها وفي هذه الحالة هي
شاشة الرن
37
الويدجت Themeهي التي تتحكم بال themeعن طريق المدخل الخاص بها data
,)(Data: isDark ? ThemeData.dark() : ThemeData.light
هو المتغير الذي قمنا بتعريفه isDark
ifمختصرة\ لفحص اذا كان ترو أو فولس ? isDark
اذا كان المتغير ترو فيتم تنفيذ أول خيار بعد عالمة االستفهام وهو الدارك ثيم
)(ThemeData.darkواذا كان فولس يتم تنفيذ الاليت ثيم )(ThemeData.light
يتم التبديل بينهم من خالل Switchوهي ويدجت
الحالة الموجودة حاليا\ Value: isDark,
عند الضغط على switchيتم تغيير الحالة\ من اليت لدراك والعكس{ )onChange: (val
;isDark = val
بدونها ال يتم التبديل\ ;)}{ )( (setState
}
Switch Widget
38
RadioButton إلنشاء
String gender = "";
Container(
margin: const EdgeInsets.all(10), مارجن للكونتينر
padding: const EdgeInsets.all(10), بادينج للكونتينر
decoration: BoxDecoration(
color: Colors.greenAccent,اعطاء لون للكونتينر
borderRadius: BorderRadius.circular(15)),حواف دائرية للكونتينر اعطاء
child: Row(
children: [
const Text("Gender: "),نص توضيحي للحقل
Expanded(
child: Column(
children: [
Row( لعرض الحقل بجانب االسم بشكل افقي
children: [
Radio( Radio Widget اختيار شيءواحد فقط
value: "m"القيمة الخاصة بالزر
groupValue: gender,
onChanged: (v) {لتغير حالة الزر عن الضغط عليه
gender = "m";
setState(() {});ال يحدث التغيير بدونها
}),
const Text('Male')
],
),
Row(
children: [
Radio(
value: "f",
groupValue: gender,
onChanged: (v) {
gender = "f";
setState(() {});
}),
const Text('FeMale')
],
)
],
),
)
],
),
),
االول والثاني وذلك\ كي نستطيع أن نختار واحدRadio موحد عن كل من الgroupValue نالحظ أن
منها فقط
الناتج من الكود السابق هكذا
40
checkBox لعمل
List<Certificate> certifications = [
Certificate("Diploma"),
Certificate("Ba"),
Certificate("Master"),
Certificate("PHD"),
];
class Certificate {
String name;
bool isSelected = false;
Certificate(this.name);
}
CheckBox
للبدء\ من أولAligment.stat
)الواجهة (اليسار
Childern: certifications.map( (e) )
التي تم انشاؤهاlist لعمل لوب على
checkBox في االعلى بدال من تكرار
عدة مرات
إلنشاء زر
هاد ممكن يجي باالمتحان كسؤال صحح الخطأ والتصحيح تبعه أنو نحط ثالث نقاط قبل
certification
الخطأ انو certificationهي listوال returnبتتعامل مع عنصر واحد فقط فلما نحط ثالث نقاط بحول
ال listلعنصر عنصر بدل من مجموعة\ وحدة
42
هذا تكملة لواجهة الفورم عند الضغط على زر sendهنجيب االسم الي دخله اليوزر في حقل
االسم وهل ذكر أم أنثى والشهادات\ الحاصل عليها ( التي تم اختيارها\ من )CheckBox
هو عبارة عن كالس قمنا بانشاءه InfoArguements
هناك أيضا طريقة أخرى للتنقل بين الواجهات وهي طريقة ال Routesوهي طريقة يتم فيها تعريف
اسم لكل واجهة ويتم استدعاءها\ من خالل االسم:
{ routes:
"userForm": (context) => const UserFormPage(),
"userInfo": (context) => UserInfoPage(),
)("PageNotFound": (context) => const PageNotFound
},
ثم نستخدم الNavigation
) "Navigation.of(context).pushReplacementNamed("userForm
) "Navigation.of(context).pushReplacementNamed("userInfo
نستخدمها\ في حال أردنا أن ننتقل إلى واجهة دون الحاجة الى pushReplacementNamed
العودة الى الواجهة السابقة مثل االنتقال من اللوجن الى الصفحة الرئيسية لسنا بحاجة الى
العودة الى اللوجن
44
TabBar
هناك محتوى جانبي يظهر عن الضغط على أيقونة في ال appBarيسمى هذه المحتوى الجانبي
Drawer
لون خلفية الصورة يظهر عندما يكون حجم الصورة اصغر من
الدائرة
const UserAccountsDrawerHeader(
accountName: Text("Ahmed"),اسم المستخدم
accountEmail: Text("Ahmed@gmail.com"),ايميل المستخدم
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.white,خلفية الصورة بيضاء
backgroundImage: AssetImage('assets/images/image0.jpg'),
),
),
امتداد الصورة من ملفات المشروع
48
ListTile
leading
trailing
ListTile
title
ListTile(
leading: const Icon(Icons.favorite_outline),
title: const Text("Favourite"),
subtitle: const Text("menu"),
trailing: IconButton( زر على شكل أيقونة
onPressed: (){}, الحدث الذي سينفذ عند الضغط على الزر
icon: const Icon(Icons.arrow_forward_ios)
),
)
49
PageView in Flutter
مبدأها مثل ال listviewولكن تختلف عنها أن كل عنصر موجود\ بداخلها\ يمثل واجهة مستقلة
بمعنى ال listviewتعرض العناصر بشكل أفقي أو عمودي في نفس الواجهة أما الpageView
تعرض العناصر بشكل أفقي في واجهات وليس في نفس الواجهة ويكون عدد الواجهات حسب
عدد عناصرها ( 3عناصر 3واجهات وهكذا) يتم التنقل ما بين الواجهات عن طريق\ ال Scrollمن
اليسار لليمين\ كما في فيسبوك كما التنقل في واتساب ما بين المحادثات والحالة\ والمكالمات
;int currentPageIndex = 0
;)(PageController pageController = PageController
هي العناصر التي سيتم التنقل بينهم فيpageViewوهم عبارة عن ثالث واجهات Childeren
50
BottomNavigationBarItem
BottomNavigationBarItem عبارة عن
lable خاصة بicon وlable يتكون
51
pageController
متغير من نوع PageControllerقمنا بتعريفه في ص 49واستخدمناه في pageViewمن ضمن
الميثود الموجود فيه هي الميثود ) jumpToPage(pageNumberمن خالل هذه الميثود نمرر لها
رقم الصفحة لالنتقال اليها
دالة تنفذ عن الضغط على itemالموجود فيonTap(){}BottomNavigationBar
currentPageIndex = value
قمنا بتعريفه في صفحة currentPageIndex 49
هو رقم الصفحة الحالية value
نستخدمها لكي يتم التغيير ;))((setState
عند النقر على أول واجهة تكون األيقونة الخاصة بها باللون األزرق ويمكن تغيير هذا اللون وكذلك\
الحال في األيقونات األخرى