Flutter Book 2020 V 01
Flutter Book 2020 V 01
نسخة مجانية
02ابريل 0202
عبدالرخمن عبمان
أكادبمبة كبابي
Kattabi Academy
قناة التلغرام
https://t.me/joinchat/AAAAAFdURPZV5Z-XSaI4Vg
الفيسبوك
Flutter-103278057864283/?referrer=whatsapp-تعلم/https://www.facebook.com
اليوتيوب
https://www.youtube.com/playlist?list=PL3I9kp6OF4yRMJRxAtCbUgnHPAOWzft1t
عن االكادبمبة
اكاديمية كتابي هي اكاديمية افتراضية مفتوحة ومتاحة مجانا للجميع ،وللمستخدم مطلق الحرية في االستفادة من الكورسات والدروس
المقدمة فيها بالوجه الذي يريد
الرؤية vision
ان تكون االكاديمية مرتعا خصبا للباحث عن التميز من خالل توفير احدث الكورسات خاصة للخريج والباحث عن الخبرة العملية
والعلمية في مجال التعليم والبحوث.
الرسالة mission
خدمة الطالب والخريجين من خالل توفير تعليم مفتوح وحر ،وخلق جسر بين الخريج وسوق العمل واالسهام في تنمية المجاالت
البحثية لالكاديميين
Objectives األهدا
.0سد الفجوة الموجود في كليات الحاسب بالتركيز على الجانب العملي في المقررات التي تقدمها االكاديمية
.3خلق جسر بين الخريج وسوق العمل وذلك بمساعدة الخريج في تعلم ما يحتاجه سوق العمل -االحترا
.5توفير بيئة تعليمية مجانية وحرة من خالل توفير مقررات مفتوحة الوصول باستخدام اليوتيوب ووسائل التواصل االجتماعية
المختلفة
على التلغرام
https://t.me/KattabiA
على الفيسبوك
https://www.facebook.com/100264501486891
على اليوتيوب
https://www.youtube.com/c/KattabiAcademy
جدول المحتويات
تعترب فلرت اطار معل حيتوي مجموعة من ا ألدوات اليت تسمح لنا بإنشاء تطبيقات تعمل عىل:
اجياد طريقة افضل لبناء تطيقات املوبيل اليت زادت احلاجة إالهيا ً
كثريا
امه ما أأضافته جوجل يف فلرت هو إاماكنية بناء تطبيقات للك الاهجزة باكفة أأنواعها
إاجياد طريقة لبناء تطبيقات iOSبصورة أأفضل من ،Swiftبناء تطبيقات الاندرويد بصورة أأفضل من ،Kotlinبناء تطبيقات ويب
بصورة أأفضل من HTML/JavaScript
مقدرتك للقيام ببناء لك هذه التطبيقات بكود واحد ( )one codebaseس تكون املزية الاقوى يف فلرت
االدوات التي نحتاجها للتطوير: .1.1
ادوات التطوير اليت حنتاج لتثبيهتا يف حواس يبنا يك نكون قادرين عىل التطوير بواسطة فلرت يه
2. IDE
• Gitعبارة عن برانمج جماين يمت توزيعه مبوجب رشوط ترخيص GNU General Public version2
• نظام التحمك يف االإصدار ( )VCSهو برانمج يساعد مطوري الربامج عىل العمل م ًعا واحلفاظ عىل جسل اكمل لعملهم.
git version
تثبيت flutter SDK .1.4.1.4
الصور التالية توحض خطوات تثبيت :flutter SDK
4
وضع مسار فلرت يف متغريات البيئة ()Environment varriables .1.4.1.7
وضع مسار فلرت يف متغري بيئة ميكنك من الوصول لربامج فلرت من اي ماكن دون احلاجة اىل ادلخول يف مسار فلرت.
ميكنك وضع مسار اجملدل binاملوجود داخل جمدل flutterيف متغريات البيئة كام هو موحض يف الصور التالية:
• انسخ املسار التايل
C:\flutter\bin
من القامئة ابدا يف ويندوز تكتب envمث اختار edit environment variables
• اضغط عىل زر edit
• ok
• ok
وضع مسار فلرت يف متغريات البيئة ( ، )C:\flutter\binميكنك من تشغيل أأي برانمج يف جمدل binمن أأي دليل
تعمل بيئة التطوير املتاكمةل كواهجة برجمة مركزية .قد يتضمن IDEانفذة برجمة لكتابة الربانمج و مصحح أأخطاء الإصالح أأخطاء الربانمج ،وحمرر مريئ
يسمح للمطورين بإنشاء وحترير واهجة املس تخدم الرسومية ( )GUIللربانمج.
تش متل IDEsأأيضً ا عىل مرتمج يس تخدم الإنشاء تطبيقات من ملفات التعلاميت الربجمية املصدر.
عادة يمت ربط الـ IDEبملرتمج اخلاص بلغة الربجمة اذلي يريد املطور اس تخداهما مثال اإذا أأردت تصممي برامج بس تخدام جافا جيب أأن تربطه مبرتمج جافا
وإاذا أأردت تصممي برانمج بواسطة فلرت فيجب أأن تربطه مبرتمج فلرت
تس تطيع اس تخدام أأي حمرر نصوص لكتابة برامج فلرت لكن هناكل ثالث بيئات تطوير مفضةل ذلكل ..ويه :
من املوقع مق بختيار النسخة املضغوطة و 11او 44بت -حسب نوع هجازك واحفظها يف هجازك
اخلطوات التالية تبني كيف حتميل فيجوال اس تديو VS Code from Microsoft
تثبيت فيجوال استديو كود .1.1.1.1
يف موقع حتميل فبجوال اس تديو كود اخرتا ملف zipمن بني خيارات التزنيل.هنا لن حتتاج اىل تثبيت وامنا فقط فك امللف املضغوط يف جمدل
يعمتد فلرت عىل التثبيت الاكمل لـ Android Studioلتوفري تبعيات نظام Androidا ألسايس اخلاص به .ومع ذكل ،ميكنك كتابة تطبيقات Flutter
يف عدد من احملررات مثل فيجوال اس تديو كود أأو انتلبج ايداي.
من موقع اندرويد اس تديو مق بختيار النسخة املناس بة كل مث مق بتحميلها
تثبيت اندرويد استديو .1.1.1.1
.1انفر نقرا مزدوجا عىل ملف تثبيت اندرويد
.1اتبع الاختيارات الافرتاضية
.1تأأكد من اتصاكل بالنرت الن هناكل اجزاء وحتديثات يمت تزنيلها من النت
محاكيiOS
•اإذا مل يكن دليك هجاز ، Macفلن تقوم بتشغيل حمايك iOSأأو حىت الرتمجة اىل نظام iOSلهذا ا ألمر.
•لتشغيل حمايك ، iOSتفتح ، Xcodeمث انتقل اإىلXcode ➤ Open Developer Tool ➤ Simulator.
•سيبد أأ تشغيل احملايك ،ومنه ميكنك حتديد أأي هجاز iOSمبا يف ذكل أأهجزة iPhoneو. iPad.
محاكيAndroid
•متا ًما مثلام يوجد الكثري من طرازات ، Androidفهناك الكثري من حماكيات ، Androidولكن هناك طريقتان شائعتان فقط للتفاعل معهم
Genymotion
AVD Manager
Genymotion
يه رشكة رحبية ،ذلا عندما تزور موقعهم عىل الويب ،فاإهنم سيبذلون قصارى هجدمه لتوجهيك حنو نسخهتم املدفوعة لكننا سرنكز عىل AVD
Managerألنه جماين متا ًما و أأكرث ش يوعًا مع مطوري فلرت
AVD Manager
AVDتعين "( ،)Android Virtual Deviceهجاز اندرويد الافرتايض".
اضغط عليه وميكنك الاختيار من بني مجيع أأنواع ا ألهجزة أأو اإنشاء هجاز خاص بك.
س تحتاج فقط اإىل تثبيت اجلهاز مرة واحدة .بعد تثبيته ،ميكن اس تخدام هذا اجلهاز اذلي متت حمااكته من أأي ، IDEسواء اكن IntelliJ / Android
Studioأأو VS Codeال حاجة الإعداد منفصل عىل كودVS.
تنفيذ البرامج
لتنفيذ تطبيقاتك البد من اس تخدام موبيل حقيق أأو افرتايض :
الس تخدام موبيل حقيق ( )Physical deviceس تقوم بتوصيهل مع حاسوبك عن طريق وصةل USBأأو ميكنك حتميل هجاز موبيل افرتايض
() )Virtual device (emulator or Simulatorلتجرب عليه تطبيقاتك
flutter doctor
وهو يقوم بلتحقق من وجود لك الادوات اليت حتتاهجا ويظهر كل تقرير بذكل وميكنك تشغيل هذا الامر من Windows PowerShell
اإذا ظهر اخلطأأ "ال توجد أأهجزة متاحة" فميكن كتابة ا ألمر التايل
flutter devices
س تظهر لك ا ألهجزة املوجودة
ملحوظة:
يعد اخلطأأ "ال توجد أأهجزة متاحة" أأ ًمرا شائ ًعا ،وميكنك عاد ًة جتاهل هذا اخلطأأ .هذا يعين أأنه يف تكل اللحظة مل يكن هناك حماكيات قيد التشغيل
ملعرفة احملاكيات اليت مت تثبيهتا اكتب ا ألمر
flutter emulators
س تظهر كل لك احملاكيات اليت مت تثبيهتا يف اجلهاز ،وميكنك تشغيل أأي مهنا بكتابة ا ألمر التايل (اذلي حيتوي عىل امس احملايك )
]flutter emulators -- launch [emulator name
وميكنك احلصول عىل تقرير مفصل عن طريق ا ألمر
flutter doctor –v
جيب عند اإنشاء مرشوعك او تطبيقك ان تكتب الامس بحلروف الصغرية فقط وميكن اس تخدام الاندراسكور للفصل بني اللكامت ،مثال
hello_world
.1افتح ويندوز ِ
بورشل
.1شغل احملايك (الاميوليرت)
.1النشاء تطببق جديد (مثال )my_first_appاكتب الامر
flutter create my_first_app
سيمت انشاء الكثري من امللفات واجملدلات اليت تعترب جزء من التطبيق (جيب ان تكون متصل بلنت)
.4عندما يكمتل انشاء التطبيق بنجاح س تظهر رساةل All done
.1الان ميكنك تنفيذ التطبيق بدلخول يف جمدل التطبيق ( )cd my_first_appمث كتابة الامر:
flutter run
مكوانت التطبيق
التطبيق اذلي مت اإنشاؤه بس تخدام flutter createيتكون من عدد من اجملدلات وامللفات ميكنك مشاهدة هذه امللفات من خالل ادلخول عىل جمدل
التطبيق بالمر:
cd my_app01
مث عرض امللفات بالمر:
dir
ما هيمنا حاليا يف لك هذه امللفات واجملدلات جمدل واحد هو libاذلي حيتوي main.dart
المراجع
1. Beginning App Development with Flutter, Create Cross-Platform Mobile Apps, Rap Payne, 2019
2. https://flutter.dev/docs/get-started/install
3. 12 August 2018, Git An introduction to Git: what it is, and how to use it, Aditya Sridhar,
https://www.freecodecamp.org/news/what-is-git-and-how-to-use-it-c341b049ae61/
4. --fast-version-control, https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F
وعبها
البنامج مثل االزرار ومربعات النص وااليقونات ر
.2التمثيل ( :)presentationوهو شكل ر
معظم أطر العمل ( )frameworksالسابقة تستخدم لكل جزء من أجزاءها لغة مختلفة ،مثال
Xamarinيستخدم للسلوك لغة C#وللتمثيل ( XAMLالجدول ادناه)
رن
لالثني معا (للسلوك وللتمثيل) اما ر
فلب فتستخدم نفس اللغة ()Dart
ه دارت ()Dart
.1.1ما ي
ر ن
وه دارت.
البمجة المستخدمة ،ي
قبل أن نتعمق يف تطوير تطبيقات فلب ،تحتاج إىل فهم لغة ر
C#
C ++
Swift
Kotlin
Java / JavaScript
ن
فستتمكن من البدء يف التطوير بواسطة دارت برسعة .
ً
نسبيا . تعتب دارت لغة بسيطة للتعلم ،ويمكنك البدء برسعة
ر
.1.2التعليقات ()Comments
التعليق يضاف للغة البمجة ليساعد نف التوثيق وفهم الكود فقط لذلك نجد أن ر
المبجم عندما يجد ي ر
أي تعليق فإنه بيتجاوزه
التعليق نوعي
.1تعليق عل سطر واحد يبدأ بالعالمة //ر
حت نهاية السطر
ن
وينته بالعالمة */
ي .2أو يف عدة سطور يبدأ بالعالمة */
ن
مثال لتعليق يف سطر الواحد
ن
مثال لتعليق يف عدة سطور
/* This
multi
Line
Comment */
رن
للنوعي هما: ر
توثيق ()documentation comment أيضا هنالك تعليق
ي
/// one line documentation comment
أو
documentation
comment
*/
ر ن
توثيق يف سطر واحد:
ي مثال لتعليق
documentation comment
*/
المتغيات .1.2
ن
المتغبات باستخدام كلمة varأو باستخدام النوع أو عن طريق كلمة
ر يف لغة Dartيتم اإلعالن عن
dynamicأو باستخدام object
مثال
أو
";String y = "test 2
أو
أو
;x = 42
; "const x = "test
ن
يمكن وضع النوع يف التعريف:
; "final x = "test
ن ر ن
يعت أن قيمتها ال
متغبات constثابتة يف وقت البجمة ( ،)compile timeمما ي
الفرق بينهما هو أن ر
ن
سء يف وقت التشغيل (.)run time يمكن أن تعتمد عل أي ي
لذلك ،إذا حاولت:
; ()const x = DateTime.now
فهذا لن ينجح.
التاىل ينجح:
ولكن األمر ي
; ()final x = DateTime.now
ن تعيي قيمة ل finalمرة نف وقت ر
يعت أنه يمكنك ر ن ن
البجمة ،وبعدها يمكنك القيام بذلك يف وقت ي مما ي
ن
تعت أنه يمكنك تعيينها مرة واحدة فقط ،حيث يجب أن تكون قيمتها التشغيل ،نف ر ن
حي أن constي ي
ر ن
معروفة يف وقت البجمة.
السالسل .1.2.2
; "String s1 = "test
االعداد .1.2.1
; int i = 5
; double d = 5.5
;()String si = i.toString
;()String sd = d.toString
;)print(i
;)print(d
;)print(si
;)print(sd
;"String si = "5
;"String sd = "5.5
;)int i = int.parse(si
;)double d = double.parse(sd
.1.2.2النوع Boolean
رن
قيمتي ،إما صواب ( )trueأو خطأ ()false تحمل إحدى
;bool test
مثال
;)lst.add(4
;))print(lst.indexOf(4
;)print(lst
() contains
() containsAll
مثال
Set ck = Set)(;
ck.add("o");
ck.remove("c");
print(ck);
print(ck.contains("o"));
ما هو المخرج ؟
Enumerations النوع.1.2.2
نحتاج هذا النوع إلنشاء نوع محدد القيم مثال
التكرار.1.2
ن
:التكرار يف دارت يمكن أن يتم بإحدى األوامر التالية
for
do
while
:1 مثال
:2 مثال
while (condition){
// do something
}
مثال :3
{do
}
)while (condition
ملحوظة
ن
:Forيفضل استخدامها يف التكرار معروف العدد َّأما while, doفتستخدمان للتكرار المعتمد عل
شط مع ر ن
ي.
Switch .1.2
مثل جافا ومعظم اللغات االخرى ،توفر دارت أمر switchالذي يستخدم لالختيار من ضمن خيارات
متعددة.
مثال
{ )switch (someVariable
; break
;break
}
ملحوظة هامة:
ن
تالحظ نرصورة وجود األمر breakيف نهاية كل خيار من خيارات switchفإذا لم تكن breakموجودة
التاىل ويستمر للذي يليه إذا لم يجد فيه breakولن يتوفق إال إذا وجد
البنامج لينفذ الخيار ي
فسينتقل ر
Breakأو وصل لنهاية .switch
ن
األمر switchيف Dartيتعامل مع نوع integerأو . string
.1.22األمر If
بي تنفيذ خيارات مختلفة البنامج متسلسال ،وتستخدم ifنف حالة اتخاذ قرار ر ن
معي ر ن عادة يتم تنفيذ ر
ي
ن
(اشبة باألمر )switchحيث ستحتاج استخدام هذا األمر يف حالة تنفيذ شطية تعتمد عل صحة
الرسط أو عدمه لتنفيذ أمر أو أوامر ما.
مثال:
)if (condition
else
.1.22ال ئ
ش viod
ئ ن
يعت إذا وضعت هذا األمر أمام دالة
تستخدم دارت مثلها مثل بقية اللغات voidللدالة عل ال س ي
ن
فيعت أنها ال ترجع قيمة
ي
مثال
{ )(void func
//Code
}
ن
تختلف دارت يف أنك ال تحتاج وضع voidأمام الدالة ،فقط يكفيك أن ال تضيف أمر returnداخل
َ
الدالة ،فتفهم دارت أن الدالة من النوع .Void
.1.21العوامل يف دارت operators
كبب من العوامل
تحتوي دارت عل عدد ر
.1.22الكائنات يف دارت )(objects
ر
كاالت: يمكنك تعريف myClassالفئة
ي
{ class myClass
}
{ class person
; String firstName
;String lastName
{ )(String sayName
}
}
ملحوظة
ر
الت نستخدمها ونتعامل معها ئ
وه يكمتغب وإنما ننش منها كائنات ) (objectsي
ر الفئة غالبا ال نستخدمها
كمتغبات داخل برامجنا
ر
يل
عند كتابة دالة مكونة من سطر واحد يمكنك أن تستخدم الرمز (>=) كما ي
;))(void main() => runApp(MyApp
يل :
ويمكن كتابتها بالطريقة التقليدية كما ي
{ )(void main
;))(runApp(MyApp
}
املراجع
Beginning App Development with Flutter, Create Cross-Platform Mobile Apps, Rap Payne, 2019
مقدمة عن الودجيت
Everything Is Widgets
ماهي الودجيت )(widget
أولي مثل زر ) (buttonأو شريط تمرير ) (scroll bar,أو تسمية ) (labelأو مربع حوار ) (dialog boxأو -
خأنة اختيار)(check box
ً ً
يمكن أن يكون شيئًا أكثر تطورا قليال مثل مربع البحث أو الخريطة الصغيرة أو الساعة أو عداد الزوار أو -
محول وحدة.
في مجال الحوسبة ،أصبح مصطلح الودجيت شائعًا عندما بدأت أنظمة التشغيل في دعم واجهة المستخدم الرسومية .حيث تم
استخدامه لإلشارة إلى كل عنصر من شأنه أن يشكل واجهة مستخدم رسومية للتطبيق.
كل من الزر أو شريط التمرير أو العالمة أو مربع االختيار أو اللوحة أو زر الخيار باسم عناصر واجهة المستخدم ).(GUI يُعر
هنالك كثير من األنواع االخرى التي سيأتي ذكرها عند الحاجة لها.
ودجيتس القيمة ()value widgets
يحتوي هذا النوع من الودجيتس على قيمة ،ربما تأتي القيم من التخزين المحلي ،أو من خدمة على األنترنت ، •
أو من المستخدم نفسه.
يتم استخدام هذه الودجيتس لعرض القيم للمستخدم والحصول على قيم من المستخدم إلى التطبيق. •
أمثلة لهذا النوع: •
،كذلك تمكنك من تحديد المساحة مثل وضع عناصر جنبًا إلى جنب أو أعلى وأسفلها ،مما يجعلها قابلة للتمرير ،أوجعلها تلت
حول العناصر بحيث ال تشعر باالزدحام ،وما إلى ذلك.
عندما يحتوي تطبيقك على عدة مشاهد ("شاشات" " ،صفحات" ،كل ما تريد االتصال به) ،ستحتاج إلى طريقة للتنقل بينها.
في هذه الحالة ستستخدم ودجيدتس التنقل .التي تتحكم في كيفية التنقل بين المشاهد .عادة ما يتم ذلك عندما ينقر المستخدم على زر
التنقل الذي يوجد على شريط عالمات التبويب أو في درج ينزلق من الجأنب األيسر من الشاشة.
ودجيتس متنوعة
السابقة وسيأتي الحديث عنها في وقت الحق. هنالك ويدجيدتس ال تندرج تحت التصاني
منها:
يمكنك تغيير خلفية الجهاز عن طريق وضع التخطيط بالكامل في حاوية وتغيير لون الخلفية أو صورتها.
تحتوي الحاوية على ويدجيت واحد ( ابن) ولكن يمكن أن يكون هذا االبن صفًا أو عمودًا أو حتى جذر شجرة ويدجيت
مثال يمكنك انشاء تخطيط من عمود ذي صفين ،يحتوي كل منهما على صورتين .يتم استخدام الحاوية لتغيير لون خلفية
العمود إلى لون رمادي أفتح ،كما مبين في الصوة التالية:
تُستخدم الحاوية بكثرة في التخطيط ،كأن تضيف حد محيط بصورة وهوامش لكل صورة ،.الشكل التالي:
مالحظة :عند عرض قائمة ثنائية األبعاد ،من المهم تحديد الصف والعمود الذي تشغله الخلية (على سبيل المثال ،اإلدخال
في عمود "السعرات الحرارية" لصف "األفوكادو")
المكدسStack
يستخدم المكدس لترتيب الويدجيتس فوق ويدجيت أساسي (غالبًا ما يكون صورة) .يمكن أن تتداخل الويدجيتس بشكل كامل
أو جزئي مع الويدجيت األساسي.
البطاقة Card
البطاقة :ينظم المعلومات ذات الصلة في صندوق ذي زوايا دائرية وظل مسقط .البطاقة موجودة في مكتبة المواد ،
وتحتوي على معلومات متصلة ببعضها ويمكن أن تتكون البطاقة من أي ويدجيت تقريبًا ،ولكن غالبًا ما يتم استخدامها
مع .ListTile
تحتوي البطاقة على ابن واحد ،ولكن يمكن أن يكون هذا االبن عمودًا أو صفًا أو قائمة أو شبكة أو ويدجيت آخر يدعم عدة
ابناء .بشكل افتراضي ،تقوم البطاقة بتقليص حجمها إلى 2 × 2بكسل .يمكنك استخدام SizedBoxلتقييد حجم البطاقة.
تأثيرا ثالثي األبعاد .يسمح لك تغيير خاصية
ً في فلتر ،تتميز البطاقة بزوايا مستديرة قليالً وظل منخفض ،مما يمنحها
ارتفاع البطاقة بالتحكم في تأثير الظل المسقط .على سبيل المثال ،يؤدي تعيين االرتفاع إلى ، 04إلى رفع البطاقة بصريًا
بعيدًا عن السطح ويؤدي إلى زيادة انتشار الظل.يؤدي تحديد قيمة غير مدعومة إلى تعطيل الظل المسقط بالكامل.
ويدجيت ListTile
للحصول على طريقة سهلة إلنشاء صف يحتوي على 3أسطر نصية وأيقونات بادئة وزائدة اختيارية .يُستخدم ListTile
كويدجيت صف متخصصة من مكتبة المواد ،بشكل شائع في Cardأو ListViewولكن يمكن استخدامه في مكان آخر.
المراجع
Techopedia, https://www.techopedia.com :
• https://flutter.dev/docs/development/ui/layout
استخدام الويدجيتس
في هذا الباب سنقدم أمثلة للويدجيتس األكثر استخداما ً وكيفية كتابة أكوادها في تطبيقك وكيفية االستفادة من خصائصها في
تعديل مظهرها.
• Container
• Text
• Image
• Icon
• RaisedButton
• PlaceHolder
• Row
• Column
الحاوية () Container
يتم استخدامها إلحتواء ودجيت بداخلها .فهي كما يبين اسمها تحتوي على ويدجيت اخرى ،في هذه الحالة تكون الحاوية هي
االب والويدجيت الذي بداخلها هو ابن (.)child
وقد تكون الحاوية هي نفسها داخل ويدجيت اخر (ابن لويدجيت اعلى).
مثال 1
هنا توجد الحاوية داخل ويدجيت اب هو ،Centerوهي ليس بداخلها ويدجيت( .هي ابن للويدجيت )Center
(Center
(child: Container
decoration: BoxDecoration(border: Border.all()),
height: 200.0,
width: 200.0,
),
),
Text(‘Hello world’),
مثال 0
هنا الحاوية توجد داخل ،Centerويوجد بداخلها ابن هو ويدجيت النص Text
(Center
(child: Container
height: 200.0,
width: 200.0,
child: Text("This is a text"),
),
),
صورة مضمنة ( : )embedded in the appهنا تكون الصورة موجودة داخل التطبيق
من االنترنت
اذا أردت استخدام صورة ثابتة في تطبيق (ال تتغير ابدا خالل عمر تطبيقك مثل الشعار أو الزخار ) ،فيجب أن تكون صورة
مضمنة.
flutter:
assets:
- assets/images/photo1.png
Image.asset('assets/images/photo1.jpg'),
أما إذا أردت صورة من االنترنت ،فتستخدم أمر كما يلي داخل ويدجيت الصورة:
Image.network(imageUrl),
تغيير حجم الصورة ()Sizing an image
عادة يتم وضع الصورة داخل حاوية ،ويتم استخدام خيارات BoxFitللتحكم في حجم الصورة وكيف تتناسب مع الحاوية التي تم
وضعها فيها.
fill •
cover •
fitHeight •
fitWidth •
contain •
مثال
في هذا المثال تم وضع ويدجيت الصورة داخل حاوية ،والحاوية توجد داخل ويدجيت التوسيط .Center
.
(Center
(child: Container
height: 200.0,
width: 200.0,
child:
Image.network("https://flutter.io/images/flutter-mark-square-100.png"),
),
),
PNG •
GIF •
WebP •
BMP •
WBMP •
ويدجيت األيقونة ()Icon
ويدجيت األيقونة يستخدم إلظهارأيقونات على تطبيقك.
يحتوي فلتر على مجموعة كبيرة من األيقونات (.)rich set of built-in icons
• https://api.flutter.dev/flutter/material/Icons-class.html
مثال 1
في هذا المثال تم وضع ويدجيت األيقونة داخل حاوية ،والحاوية داخل ويدجيت توسيط.
(Center
(child: Container
height: 200.0,
width: 200.0,
child: Icon(Icons.flag),
),
),
مثال 0
هذا الكود يوضح كيف يمكنك االستفادة من بعض خصائص ويدجيت األيقونة إلظهار أيقونة (كيكة) بلون أحمر وحجم 022
Icon(
Icons.cake,
color: Colors.red,
size: 200,
)
PlaceHolder ويدجيت
تحجز مكان في التطبيق
مثال
Center(
child: Container(
height: 200.0,
width: 200.0,
child: Placeholder(),
),
),
Raisedbutton ويدجيت
onPressed ويمكن تنفيذ كود معين عند الضغط على هذا الزر بوضعه في، لعمل زرRaisedbutton يمكنك استخدام ويدجيت
الموجودة في هذا الويجيت
مثال
Center(
child: Container(
height: 200.0,
width: 200.0,
child: RaisedButton(
onPressed: () => print("on pressed"),
child: Text("BUTTON"),
color: Colors.blue,
),
),
),
مثال
في الكود التالي تم وضع ويدجيت عمود داخل ويدجيت توسيط .يتكون ويدجيت العمود من ثالث حاويات ،كل حاوية بلون مختلف.
(Center
(child: Column
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
[>children: <Widget
(Container
height: 20.0,
width: 20.0,
color: Colors.red,
),
(Container
height: 20.0,
width: 20.0,
color: Colors.green,
),
(Container
height: 20.0,
width: 20.0,
color: Colors.yellow,
),
],
),
),
. كل حاوية بلون مختلف، يتكون ويدجيت السطر من ثالث حاويات.في الكود التالي تم وضع ويدجيت سطر داخل ويدجيت توسيط
Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
height: 20.0,
width: 20.0,
color: Colors.red,
),
Container(
height: 20.0,
width: 20.0,
color: Colors.green,
),
Container(
height: 20.0,
width: 20.0,
color: Colors.yellow,
),
],
),
),
المراجع
5. Beginning App Development with Flutter, Create Cross-Platform Mobile Apps, Rap Payne, 2019
ويدجيتس اإلدخال
مقدمة
هنالك مجموعة من الودجيتس تستخدم إلستقبال بيانات من المستخدم وتوصيلها لتطبيقك لمعالجتها أو اتخاذ قرار ِوفقا ً لها .سنتحدث
في هذا الباب عنها :
ويدجيت TextField
تستخدم هذه الودجيت الدخال نص الى التطبيق .هذه الويدجيتس لديها خاصية تسمى ،onChangedوالتي تعمل بمجرد تغير القيم
المدخلة من المستخدم .أي كلما يضغط المستخدم على مفتاح في لوحة المفاتيح ستستلم هذه الخاصية ()onChangedالنص المدخل
ليتم معالجته.
مثال 1
في هذا المثال يقبل الويدجيت إدخال نص من المستخدم ،وكلما ضغط المستخدم على حرف ستعمل onChangedوتخزن القيمة
المدخلة في المتغير valCpyويتم طباعة هذا المدخل في نفس الوقت على الكونوسل باالمر ;).print(valCpy
يمكن كتابة الكود بأي واحدة من الطريقتين ادناه (الفرق فقط في استخدام textأومتغيرنصي).
مثال لو أدخلت كلمة سالم من الكبيورد في المثال أعاله ستعمل خاصية onChangedمع كل ضغطة على الكيبورد فيظهر في
الكونسول الناتج التالي:
يمكنك التعديل في خواص الويدجيت TextFieldليمكنك من استخدامه لبيانات ال ترى وإنما تظهر في مربع النص في شكل نجوم،
كما مبين في الكود التالي:
(TextField
obscureText: true,
(decoration: InputDecoration
labelText: 'Password',
),
;)
يمكننا استخدام خاصية keyboardTypeفي ويدجيت TextFieldإلظهار سوفت كيبورد لتقليل أخطاء اإلدخال ،مثال لو كنت تريد
من المستخدم أن يدخل أرقام فقط فستختار TextInputType.numberكما في الكود التالي:
(return TextField
keyboardType: TextInputType.number,
;)
مثال
مثال لو أردت عمل كلمة مرور من أرقام فقط ،فيمكنك استخدام خاصية كلمة المرور وتحديد السوفت كيبورد ليكون رقمي كما مبين
أدناه:
تخصيص ويدجيت TextFieldالدخال ايميل ()Input email
المثال التالي يوضح كيف يمكنك مساعدة المستخدم إلدخال إيميل الى مربع النص
ويدجيت Checkbox
مثال
في المثال التالي تعمل الخاصية onChangedعند ما يضغط المستخدم على مربع االختيار ويطبع القيمة المنطقية على الكونسول.
(Checkbox (Checkbox
value: true, value: true,
)onChanged: (bool val) => print(val {)onChanged: (bool val
), ;)print(val
;checkboxValue = val
;)}
المخرج
انشاء مربع اختيار داخل صف مع إضافة نص يوضح لم خصص مربع االختيار (صف داخلة ويدجيت مربع اختيار +ويدجيت نص)
ويدجيت Radio button
زر ريديو في تطبيق في أبسط صوره ،يكون كما يلي:
مثال 0
يمكنك اضافة خاصية onChangedلزر ريديو أو اضافة groupValueلربط عدد من ازرار الريديو مع بعض لتتيح للمستخدم
اختيار خيار واحد فقط من ضمن خيارات ,ووضع كل االزرار في صف واحد (للتنسيق).
Row(
children: <Widget>[
Radio(
value: 0,
groupValue : _radioValue,
onChanged : (int inValue) {
_radioValue = inValue;
}),
Radio (
value: 1,
groupValue : _radioValue,
onChanged : (int inValue) {
_radioValue = inValue;
}
)
]),
الكود والمخرج
مثال
Center(
child: Row(
children: <Widget>[
Radio(
value: 0,
groupValue : _radioValue,
onChanged : (int inValue) {
_radioValue = inValue;
}),
Radio (
value: 1,
groupValue : _radioValue,
onChanged : (int inValue) {
_radioValue = inValue;
}
)
]),
),
مثال
وضعها في صف
Center(
child: Row(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
Radio(
value: 0,
groupValue : _radioValue,
onChanged : (int inValue) {
_radioValue = inValue;
}),
Radio (
value: 1,
groupValue : _radioValue,
onChanged : (int inValue) {
_radioValue = inValue;
}
)
]),
),
مثال
• Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Radio(
value: 0,
groupValue : _radioValue,
onChanged : (int inValue) {
_radioValue = inValue;
}),
Text("Male"),
Radio (
value: 1,
groupValue : _radioValue,
onChanged : (int inValue) {
_radioValue = inValue;
}
),
Text("FeMale")
]),
),
Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Radio(
value: 0,
groupValue : _radioValue,
onChanged : (int inValue) {
_radioValue = inValue;
}),
Text("Male"),
Radio (
value: 1,
groupValue : _radioValue,
onChanged : (int inValue) {
_radioValue = inValue;
}
),
Text("FeMale")
]),
),
Sliders ويدجيت
Slider(
label: _value.toString(),
divisions: 100,
value: _value,
),
• Center(
child: Slider(
label: _value.toString(),
min: 0, max: 100,
divisions: 100,
value: _value,
onChanged: (double val) => _value = val,
),
),
)Dropdown menu( ويدجيت القائمة المنسدلة
ويدجيت لعمل قائمة منسدلة في تطبيقك
....
Center(
child:
DropdownButton<SearchType>(
value: _searchType,
items: const <DropdownMenuItem<SearchType>>[
DropdownMenuItem<SearchType>(
child:Text('Web'),
value: SearchType.web,
DropdownMenuItem<SearchType>(
child:Text('Image'),
value: SearchType.image,
),
DropdownMenuItem<SearchType>(
child:Text('News'),
value: SearchType.news,
),
),
DropdownMenuItem<SearchType>(
child:Text('Shopping'),
value: SearchType.shopping,
),
],
onChanged: (SearchType val) => _searchType = val,
),
),
المراجع
6. Beginning App Development with Flutter, Create Cross-Platform Mobile Apps, Rap Payne, 2019
اسكافول
ويدجيت اسكافولد Scafold
يمكنك استخدام ويدجيت اسكافولد إلنشاء تطبيق محمول لألغراض العامة وتحتوي تقريبًا على كل ما تحتاجه إلنشاء تطبيق فعال
وسريع االستجابة.
ن ر
الت يمكنك اضافتها فيه .حيث يمكنك وضع ويدجيت يف كل
الصور التالية توضح اجزاء AppBarي
جزء من اجزائه.
:
:مثال
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body:
Text('Hello World :'),
),
);
}
المخؤج
AppBar يمكننا تعديل المثال السابق بإضافة خلفية وعنوان لـ
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Welcome to Kattabi Academy"),
backgroundColor: Colors.deepOrangeAccent,
),
body:
Center(child: Text('Hello World')),
),
);
}
}
المخرج
مثل تغيير لون الخلفية واستخدام األيقونات بدالً من النص كعنوانAppBar يمكننا اضافة خصائص مختلفة على شاشة
مثال تغيير العنوان من ويدجيت نص الى ويدجيت ايقونة
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Icon(Icons.home),
backgroundColor: Colors.deepOrangeAccent,
),
body:
Center(child: Text('Hello World')),
),
);
}
}
زر اإلجراء العائم Floating Action Button
زر اإلجراء العائم هو زر رمز دائري يتم عرضه طوال الوقت وهو مخصص بشكل عام للترويج إلجراء أساسي أو األكثر
استخدا ًما على الشاشة .مثالً بالنسبة لتطبيقات البريد اإللكتروني الشائعة مثل ، Gmailيتم استخدامه إلنشاء بريد إلكتروني جديد.
يتم إنشاء زر إجراء عائم باستخدام ويدجيت () FloatingActionButtonبحد أدنى من معلمتين ُمنشئتين تسمى " ":childو
" ":onPressedيتم استخدام " ":childإلضافة التصني بينما يتم استخدام " ، ":onPressedوالذي يتم استدعاؤه في كل مرة
يضغط فيها المستخدم على الزر ،لتشغيل اإلجراء المطلوب.
على الرغم من أنه يمكننا عرض النصوص في زر اإلجراء العائم ،إال أنه من االفضل استخدام الرموز /الصور بدالً من ذلك ،
لسببين هما:
.0من الصعب احتواء النص الطويل والهادئ داخل المساحة الصغيرة لزر اإلجراء العائم
مثال إضافة زر عائم عند الضغط عليه يقوم بطباعة الرسالة التالية في كونسول
;'import 'package:flutter/material.dart
;))(void main() => runApp(MyApp
{ class MyApp extends StatelessWidget
@override
{ )Widget build(BuildContext context
(return MaterialApp
(home: Scaffold
///////////////////////////////////////////////////////////////
(appBar: AppBar
title: Icon(Icons.home), //Text("Welcome to Kattabi Academy"),
backgroundColor: Colors.deepOrangeAccent,
),
///////////////////////////////////////////////////////////////
body:
Center(child: Text('Hello World')),
/////////////////////////////////////////////////////////////////
(floatingActionButton: FloatingActionButton
child: Icon(Icons.add),
{)(onPressed:
;)"print("you pressed the button...
},
),
////////////////////////////////////////////////////////////////////
),
;)
}
}
)+(إضافة نص ليظهر داخل الزر العائم بدالً من األيقونة بدال من االيثونة
Text("add"),
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
///////////////////////////////////////////////////////////////
appBar: AppBar(
title:Text("Welcome to Kattabi Academy"),
backgroundColor: Colors.deepOrangeAccent,
),
///////////////////////////////////////////////////////////////
body:
Center(child: Text('Hello World')),
/////////////////////////////////////////////////////////////////
floatingActionButton: FloatingActionButton(
child: Text("add"),
onPressed:(){
print("you pressed the button...");
},
),
////////////////////////////////////////////////////////////////////
),
);
}
}
شريط التنقل السفلي Bottom Navigation Bar
شريط التنقل السفلي ،يشبه AppBarفهو شريط أفقي في أسفل الشاشة .يمكن أن يحتوي على عناصر متعددة ويمكنه استخدام
تسميات نصية أو رموز أو مزيج من كليهما.يتم إنشاء شريط التنقل السفلي بشكل عام لعرض الرسائل وكذلك لتوفير إجراءات
اختصارات محددة للصفحة.
توجد أداة تسمى " "BottomNavigationBarإلنشاء نفس األداة ،ومع ذلك ،باستخدام " "Scaffoldو
" "FloatingActionButtonنستخدم أداة " "BottomAppBarألنها توفر مساحة لزر اإلجراء العائم وال تتداخل معه.
مثال يمكنك إنشاء شريط تنقل سفلي باستخدام " AppBar "BottomAppBarمع شريط التنقل السفلي ايضا يمكننا عرض أدوات
متعددة داخل )(BottomAppBarباستخدام ويدجيت مثل )( Rowتحتوي على ويدجيتس فرعية متعددة بداخلها .يمكن أن
يحتوي شريط التنقل السفلي على مجموعة من النصوص والرموز .يمكن أن تكون الرموز مجرد رمز عرض ثابت أو زر رمز مع
اإلجراءات المرتبطة به
;'import 'package:flutter/material.dart
;))(void main() => runApp(MyApp
{ class MyApp extends StatelessWidget
@override
{ )Widget build(BuildContext context
(return MaterialApp
(home: Scaffold
///////////////////////////////////////////////////////////////
(appBar: AppBar
title:Text("Welcome to Kattabi Academy"),
backgroundColor: Colors.deepOrangeAccent,
),
///////////////////////////////////////////////////////////////
body:
Center(child: Text('Hello World')),
/////////////////////////////////////////////////////////////////
floatingActionButton: FloatingActionButton(
child: Text("add"),
onPressed:(){
print("you pressed the button...");
},
),
bottomNavigationBar:BottomAppBar(
child: Text("bottom bar "),
),
),
);
}
}
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
///////////////////////////////////////////////////////////////
appBar: AppBar(
title:Text("Welcome to Kattabi Academy"),
backgroundColor: Colors.deepOrangeAccent,
),
///////////////////////////////////////////////////////////////
body:
Center(child: Text('Hello World')),
/////////////////////////////////////////////////////////////////
floatingActionButton: FloatingActionButton(
child: Text("add"),
//Icon(Icons.add),
onPressed:(){
print("you pressed the button...");
},
),
bottomNavigationBar:BottomAppBar(
child: Row(
children: <Widget> [
Text("bottom bar "),
Icon(Icons.home),
],
),
),
),
);
}
}
() وتحديد معلمة االرتفاع لهاContainer" يمكنك زيادة حجم شريط التنقل السفلي عن طريق احاطة االبن بحاوية
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
///////////////////////////////////////////////////////////////
appBar: AppBar(
title:Text("Welcome to Kattabi Academy"),
backgroundColor: Colors.deepOrangeAccent,
),
///////////////////////////////////////////////////////////////
body:
Center(child: Text('Hello World')),
/////////////////////////////////////////////////////////////////
floatingActionButton: FloatingActionButton(
child: Text("add"),
//Icon(Icons.add),
onPressed:(){
print("you pressed the button...");
},
),
bottomNavigationBar:BottomAppBar(
child: Container(
height: 100.0,
child: Row(
children: <Widget> [
Text("bottom bar "),
Icon(Icons.home),
],
),
),
),
),
);
}
}
فهو يشترك.يأخذ زر التذييل الثابت مجموعة من األدوات وليس له خصائص مرتبطة به مثل لون الخلفية أو االرتفاع وما إلى ذلك
. في لون الخلفية مع خلفية اسكافولد
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
///////////////////////////////////////////////////////////////
appBar: AppBar(
title:Text("Welcome to Kattabi Academy"),
backgroundColor: Colors.deepOrangeAccent,
),
///////////////////////////////////////////////////////////////
body:
Center(child: Text('Hello World')),
/////////////////////////////////////////////////////////////////
floatingActionButton: FloatingActionButton(
child: Text("add"),
//Icon(Icons.add),
onPressed:(){
print("you pressed the button...");
},
),
bottomNavigationBar:BottomAppBar(
child: Container(
height: 100.0,
child: Row(
children: <Widget> [
Text("bottom bar "),
Icon(Icons.home),
],
),
),
),
persistentFooterButtons: <Widget>[
IconButton(icon:Icon(Icons.account_box), onPressed:null ,),
IconButton(icon:Icon(Icons.account_circle), onPressed:null ,)
], ),
);
}
}
تمرين
في الدروس السابقة وعدل االكواد فيهHello worldارجع لنسخ برنامجنا االول
غير الشريط العلوي مرة بنص عربي ومرة بايقونة
غير في جسم اسكافولد وبدل ،جرب تغيير لون الخلفية
اض ازرار سفلية في التطبيق
زر عائم
زر ثابت
وغيره
المراجع
https://proandroiddev.com/flutter-material-design-using-scaffold-appbar-body-bottom-navigation-
floating-action-f84d71e68c76
تخطيط تطبيقك
https://flutter.dev/docs/development/ui/layout
Stateful and stateless widgets .1.1
الويدجيت نوعان هما
stateful .1
stateless .0
النوع األول يتغير عندما يتفاعل المستخدم معه وأما النوع الثاني فيظل شكله ثابت ال يتغيروال يتفاعل مع المستخدم
أمثلة لألدوات (الويدجيتس ) التي ال تتفاعل مع المستخدم:
Icon
IconButton
Text
تعتبر هذه الويدجيتس Stateless widgetsهي فئات فرعية subclassمن الويدجيت StatelessWidget
أما الويدجيت الديناميكية stateful widgetفهي تغير مظهرها استجابةً لألحداث الناتجة عن تفاعالت المستخدم أوعندما
تتلقى البيانات.
امثلة لهذا النوع
Checkbox
Radio
Slider
InkWell
Form
TextField
تعتبر هذه األدوات فئات فرعية من StatefulWidgetيتم تخزين حالة الويدجيت A widget’s stateفي كائن الحالة
State objectمما يفصل حالة األداة من مظهرها.
تتكون الحالة من القيم التي يمكن أن تتغير ،مثل القيمة الحالية لشريط التمرير أو ما إذا تم تحديد مربع اختيار.
عندما تتغير حالة األداة ،يقوم كائن الحالة state objectباستدعاء الميثود التالي ( ) setStateالذي يخبر اإلطار (الفريم
ويرك) بإعادة رسم األداة
main.dart
pubspec.yaml
)الملف االول به كود المشروع والملف التاني به بيانات تهيئة المشروع مثل تحديد مسار الصور في تطبيقك (اين توجد
.سنبدل هذين الملفين بملفين اخرين
:)lib افتح الملف التالي في المشروع (موجود في المجلد
main.dart
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
@override
child: Row(
children: [
Expanded(
/*1*/
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/*2*/
Container(
child: Text(
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
Text(
'Kandersteg, Switzerland',
style: TextStyle(
color: Colors.grey[500],
),
),
],
),
),
/*3*/
Icon(
Icons.star,
color: Colors.red[500],
),
Text('41'),
],
),
);
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
],
),
);
child: Text(
'Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese '
'Alps. Situated 1,578 meters above sea level, it is one of the '
'half-hour walk through pastures and pine forest, leads you to the '
'enjoyed here include rowing, and riding the summer toboggan run.',
softWrap: true,
),
);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter layout demo'),
),
body: ListView(
children: [
Image.asset(
'images/lake.jpg',
width: 600,
height: 240,
fit: BoxFit.cover,
),
titleSection,
buttonSection,
textSection,
],
),
),
);
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: Text(
label,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w400,
color: color,
),
),
),
],
;)
}
}
assets:
- images/lake.jpg
يمكن أن تحتوي الويدجيت على ويدجيت أخري وهنا نستخدم كلمة childلنُعلم الويدجيت أن بداخلها ويدجيت ابن
وأيضا يمكن أن تحتوي الويدجيت على عدد كبير من الويدجيتس (أبناء) ونستخدم كلمة childrenمثل الويدجيت
Rowوالويدجيت Column
يمكنك إنشاء تخطيط عن طريق إنشاء ويدجيتس لبناء ويدجيتس أكثر تعقيدًا .مثال لعرض الشكل أدناه فإننا نستخدم 3
ويدجيتس لعرض ثالثة أيقونات و 3ويدجيتس نصية لوضعها تحت األيقونات وكل هذا المحتوي سيكون داخل ويدجيت
(غير مرئي) هو ويدجيت الصف Rowيعني
3 Icons
)3 Text (used as labels
مثال
يمكنك عمل الشكل التالي في تطبيقك بـ:
Row
Column
ويدجيت العمود نفسها في الشكل أعاله تحتوي على صفوف داخلها كما يظهر في الشكل أدناه
Row )
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/pic1.jpg,)'
Image.asset('images/pic2.jpg,)'
Image.asset('images/pic3.jpg,)'
],
;)
هنا ستظهر الصور على نفس الصف وألننا استخدمنا spaceEvenlyفستكون المسافات بين الصورة متساوية
لتجربة هذا الكود :يجب أن تكون لديك ثالث صور في مجلد اسمه imagedداخل تطبيقك ويكون هذا المجلد معرف في
الملف pubspec.yaml
الكود
(Column
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
[ children:
Image.asset('images/pic1.jpg'),
Image.asset('images/pic2.jpg'),
Image.asset('images/pic3.jpg,'),
],
;)
ملحوظة
لو قارنت بين كود الصف وكود العمود تجد أن الفرق فقط في الكلمة االولى Rowأو Columnباقي الكود كما هو
Row )
crossAxisAlignment: CrossAxisAlignment.center,
children :[
Expanded(child: Image.asset('images/pic1.jpg')),
Expanded(
flex: 2,
child: Image.asset('images/pic2.jpg')),
Expanded(
child: Image.asset('images/pic3.jpg')),
]),
mainAxisSize: MainAxisSize.min,
children :[
ملحوظة هامة
تم استخدام متغير هو startsمن النوع varلحفظ كود إنشاء النجوم داخل صف بحيث يمكنك استخدام هذا المتغير في
مكان اخر بدال عن كتابة الكود مرة اخرى وهو يشبه بذلك استخدام الدوال في اللغات االخرى
mainAxisSize: MainAxisSize.min,
children[ :
],),
padding: EdgeInsets.all(20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children :[
stars,
Text(‘102 Reviews',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w800,
fontFamily: 'Roboto',
letterSpacing: 0.5,
fontSize: 20,
),
),
],
),
),
color: Colors.black,
fontWeight: FontWeight.w800,
fontFamily: 'Roboto',
letterSpacing: 0.5,
fontSize: 18,
height: 2,
);
style: descTextStyle,
child: Container(
padding: EdgeInsets.all(20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: [
Text('PREP:'),
Text('25 min'),
],
),
Column(
children: [
Text('COOK:'),
Text('1 hr'),
],
),
Column(
children: [
Text('FEEDS:'),
Text('4-6'),
],
),
],
),
),
);
.1.11كود الصورة مع العمود (الشكل النهائي)
متغير العمود األيسر يحتوي على نص وصف التقييم (النجوم) وصف لوصف الصورة (يحتوي ثالث أعمدة)
(child: Column
[ children:
titleText,
subTitle,
],
),
;)
أخيرا ،يتم إنشاء واجهة المستخدم مع الصف بأكمله (الذي يحتوي على
ً يتم وضع العمود األيسر في حاوية لتقييد عرضه.
العمود األيسر والصورة) في ويدجيت بطاقة cardكما موضح في الصور المرفقة.
(body: Center
(child: Container
height: 600,
(child: Card
(child: Row
crossAxisAlignment: CrossAxisAlignment.start,
[ children:
(Container
width: 440,
child: leftColumn,
),
mainImage,
],
),
),
),
),
المراجع
تم جمع دروس هذا الباب من موقع فلتر التالي:
https://flutter.dev/docs/development/ui/layout
وتم شرح كل الدروس من هذا الموقع مباشرة في الفيديو التالي:.
https://youtu.be/IYUtIoXwto8
يتم إنشاء كل ويدجيت في فلتر بواسطة دالة البناء) (buildوتأخذ هذه الدالة ال ُمدخل من النوع ( )BuildContextفنكتب الكود كما يلي:
}
ال ُمدخل ( )BuildContextيحدد مكان الويدجيت في شجرة الويدجيت التي تخص تطبيقك
لذلك اطلقنا على األول ساكن وعلى الثاني ديناميكي .بالنسبة للنوع الثاني (الديناميكي) ،يتم القيام به عن طريق فئتين هما:
فعندما تتغير حالة الويدجيت فإن كائن الحالة ( )state objectسيستدعي الطريقة )( setStateالتي تطلب من إطار العمل
( )frameworkإعادة رسم الويدجيت ()redraw the widget
ستقوم باستبدال ويدجتين بدون حالة هما النجمة الحمراء الصلبة والعدد الرقمي المجاور لها ،بويدجيت مخصصة واحدة تدير صفًا
يحتوي على ويدجتين فرعيين هما :
IconButton
Text
تدير فئة FavoriteWidgetحالتها الخاصة بها ،لذا فهي تعمل ( )overridesللدالة )( createStateبدالة تقوم بإنشاء كائن حالة
()state object
الكود
@override
}
األعضاء أو الفئات التي تبدأ بشرطة سفلية (_) تعتبر خاصة (في لغة دارت)
Members or classes that start with an underscore (_) are private.
المصدرhttps://flutter.dev/docs/development/ui/interactive#managing-state :
خالصة هذا الدرس هو أننا سنستبدل األيقونة العادية التي في التطبيق بزر ايقونة ،الن زر االيقونة لديه خاصية onPressedالتي
سنضع فيها كود يغير شكل الويدجيت والقيمة الموجودة في النص من 42الى 41مثال.
تقوم الفئة _FavoriteWidgetStateبتخزين البيانات القابلة للتغيير أي التي يمكن أن تتغير على مدار حياة الويدجيت.
عندما يتم تشغيل التطبيق ألول مرة ،تعرض واجهة المستخدم نجمة حمراء صلبة ،كحالة "مفضلة" ،إلى جانب 41إعجابًا .يتم
تخزين هذه القيم في حقلي _isFavoritedو _favoriteCountكما يلي:
تحدد الفئة أيضًا طريقة البناء ( )build() methodالتي تنشئ صفًا يحتوي على زر ونص ( )IconButton & textيمكنك
استخدام زر ايقونة ( ) IconButtonبدالً من االيقونة ألنه يحتوي على خاصية onPressedالتي تحدد وظيفة رد االتصال
) (_toggleFavoriteلمعالجة النقر .
تنبيه :يؤدي وضع النص في SizedBoxوتعيين عرضه إلى منع حدوث "قفزة" ،يمكن مالحظتها عندما يتغير النص بين 42و
( 41ألن هذه القيم لها عروض مختلفة)
الدالة )( _toggleFavoriteالتي تعمل عند الضغط على ، IconButtonتستدعي الدالة )(setState
استدعاء )( setStateيخبر اإلطار بأن حالة األداة قد تغيرت وأن الويدجيت يجب إعادة رسمها .
تقوم الدالة لـ )( setStateبتبديل واجهة المستخدم بين هاتين الحالتين:
الكود
الكود
قم باستبدال االوامر المعلمة باالصفر في التطبيق الساكن بامر الويدجيت في التطبيق التفاعلي (ايضا معلم باالصفر) ،كما يلي:
[ children: [ children:
Expanded( Expanded(
/*1*/ /*1*/
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment.start, CrossAxisAlignment.start,
children: [ children: [
/*2*/ /*2*/
Container( Container(
), ),
), ),
), ),
Text( Text(
), ),
), ),
], ],
), ),
), ),
/*3*/ /*3*/
FavoriteWidget(), Icon(
], Icons.star,
;) ),
Text('41'),
],
),
;)
عندما تعيد تحميل التطبيق ،يجب أن يستجيب رمز النجمة اآلن لنقرات المستخدم ويتغير بين 42والنجمة المفرغة الى 41والنجمة
الحمراء.
إذا كانت الحالة المعنية هي بيانات المستخدم ،على سبيل المثال الوضع المحدد أو غير المحدد لمربع االختيار
( ،)Checkboxأو موضع شريط التمرير( ،)sliderفمن األفضل إدارة الحالة بواسطة الويدجيت الرئيسية (
األب).
إذا كانت الحالة المعنية جمالية ،على سبيل المثال الرسوم المتحركة ،فمن األفضل إدارة الحالة بواسطة
الويدجيت نفسها.
إذا كنت في شك ،فابدأ بإدارة الحالة في الويدجيت االب.
في تطبيقك ومسحها ووضع الكود أدناه وتشغيل البرنامج سيظهر لك نفس شكل التطبيق السابق ولكن عندmain.dart يمكنك فتح
النقر على نجمة اإلعجاب سيتغير شكلها وتتغير قيمة عداد اإلعجاب
@override
void _toggleFavorite() {
setState(() {
if (_isFavorited) {
_favoriteCount -= 1;
_isFavorited = false;
} else {
_favoriteCount += 1;
_isFavorited = true;
});
@override
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: EdgeInsets.all(0),
child: IconButton(
color: Colors.red[500],
onPressed: _toggleFavorite,
),
),
SizedBox(
width: 18,
child: Container(
child: Text('$_favoriteCount'),
),
),
],
);
// ···
void main() {
runApp(MyApp());
@override
child: Row(
children: [
Expanded(
/*1*/
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/*2*/
Container(
child: Text(
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
Text(
'Kandersteg, Switzerland',
style: TextStyle(
color: Colors.grey[500],
),
),
],
),
),
/*3*/
FavoriteWidget(),
],
),
);
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
],
),
);
child: Text(
'Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese '
'Alps. Situated 1,578 meters above sea level, it is one of the '
'half-hour walk through pastures and pine forest, leads you to the '
'enjoyed here include rowing, and riding the summer toboggan run.',
softWrap: true,
),
);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
body: ListView(
children: [
Image.asset(
'images/lake.jpg',
width: 600,
height: 240,
fit: BoxFit.cover,
),
titleSection,
buttonSection,
textSection,
],),
),
);
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: Text(
label,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w400,
color: color,
),
),
),
],
);
@override
void _toggleFavorite() {
setState(() {
if (_isFavorited) {
_favoriteCount -= 1;
_isFavorited = false;
} else {
_favoriteCount += 1;
_isFavorited = true;
}); }
FavoriteWidget)(
فتقوم بإظهار النجمة وعداد اإلعجاب في المكان الذي استدعيتها فيه وتنتظر من المستخدم أن ينقرعلى النجمة التي اظهرتها لتستجيب
له بتغيير شكلها وقيمة االعجاب
تمرين اختياري
يمكنك تعديل تطبيق البحيرة قليال حتى تشعر بالثقة بأنك قد بدأت بعمل تطبيقك الخاص.
المراجع
Adding interactivity to your Flutter app, https://flutter.dev/docs/development/ui/interactive
main.dart
مقدمة
في هذا الباب سنستفيد من كل ما سبق لعمل تطبيق متكامل (ساكن) ،بحيث نشرح كل خطوة فيه
ونبين شكل المخرج كيف سيكون في كل خطوة من هذه الخطوات.
كل العمل هنا سيكون في ملف المشروع الرئيسي وهو ،main.dartوفد نحتاج الى تعديل
طفيف في ملف التهيئة pubspec.yaml
صفات الويدجيتس
قبل البدء سنذكر ونستذكر صفات الويدجيتس التي تساعدنا في فهم االكواد.
عرفنا أن كل شئ في فلتر عبارة عن ودجيت وهذا إلى حد كبير يبين أنها ليست سوى تسلسل
هرمي عمالق من الوديجيدتس ( )hierarchy of widgetsوهذا التسلسل الهرمي يسمى في
فلتر ب "شجرة الودجيت" (.)widget tree
كما ترى ،فإن معظم الودجيدتس يمكن أن يكون لها ابن واحد أو أكثر ( . )childernويمكن
أن يكون لكل ابن من هؤالء األبناء ابن واحد أو أكثر ،وهكذا.
جميع الوجيدتس عبارة عن فئات ، Dartوعادة يجب أن تحتوي على الدالة () buildالتي
ترجع هذه الدالة ودجيدتس أخرى (.)return other widgets
هناك بعض االستثناءات القليلة جدًا لهذا ،بعض الودجيدتس ذات المستوى المنخفض مثل
ودجيت النص ( )Text widgetوالتي تُرجع نو ً
عا بدائيًا (سلسلة ())string
النظر عن هذا المتطلب ،على مستوى الكود ،فإن الودجيت هو مجرد فئة Dart بصر
ال تختل عن بقية الفئات في شئ
فئيتي فلتر Stateless & Stateful Widget
ترث الويجيدتس عادة واحدا من الفئات القياسية التي توفرها فلتر .
StatelessWidget
StatefulWidget
الودجيت الذي يرث StatelessWidgetال يتغير أبدًا(ساكن) ،ويطلق عليه stateless widget
ألنه حالته ال تتغير .
تستخدم دارت معلوم أن فلتر تستخدم لغة دارت ( )Dartفي السلوك والتمثيل (الشكل) ،السؤال هنا كي
في تصميم الشكل؟.
ليس هنالك اشكال جاهزة لالزرار والقوائم ومربعات النصوص وغيرها ،وانما هنالك كود لكل شكل
يكتب بلغة دارات (كما رأينا في االبواب السابقة),
مثال ()1
سنبدأ بإنشاء اول تطبيق بابسط ما يكون ،كل العمل سيكون في مل ، main.dartلذلك لو اردت ان
تتابع معنا عملي فعليك بنسخ الكود التالي ومسح محتوى main.dartثم لصقه هناك ،بعدها نفذ ومن
المفترض ان يكون المخرج عندك كالصورة التي تلي هذا الكود.
المخرج
الصورة التالية هي نتيجة تنفيذ البرنامج اعاله ،ونالحظ ان الشريط االزرق فارغ ( )AppBarالننا
لم نضع فيه عنوان ،ايضا نالحظ ان العبارة Learn Flutterظهرت في الركن االعلى االيسر
من الجسم ( ،)bodyألننا لم نستخدم ويدجيت تنسييق مثل Center
مثال ()2
عنوان في AppBar
تنبيه هام :اذا وضعت ويدجيت داخل ويدجيت البد من استخدام childلذلك
)3( مثال
في هذا المثال سنستخدم. دون التعمق فيها،في االمثلة السابقة استخدمنا ويدجيت النص الظهار نص
لتنسيق النصstyle
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
/////////////////////////////////////////////////////
appBar: AppBar(title: Text("))"كتابي اكاديمية,
/////////////////////////////////////////////////////
body:
Center(
child:
ت
Text( ' ' فلتر علم,
style: TextStyle(
fontSize: 48.0, // حجم الخط
color: Colors.deepOrange, // لون الخط
decoration: TextDecoration.underline, // خط تحت النص
fontStyle: FontStyle.italic, // خطا مائل
fontWeight: FontWeight.bold, // خط عريض
),
),
),
),
);
}
}
المخرج
. النص االول هو النص في المثال السابق مع تنسيقه،عمود نضع فيه ثالث نصوص سنضي
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text(")"كتابي اكاديمية,
leading: IconButton(
icon: Icon(Icons.menu),
onPressed: () { },
),
),
////////////////////////////////////////////////////////////////
body:
Column(crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.
spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
ت
Text(' ' فلتر علم,
style: TextStyle(
fontSize: 48.0,
color: Colors.deepOrange,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
),
),
Text(')'عثمان عيدالرحمن,
Text(' )' كتابي اكاديمية,
Padding(padding: EdgeInsets.all(16.0),),
],
),
),
);
}
}
المخرج
)5( مثال
)6( مثال
) لويدجيت النص الول خلية في العمود (تعلم فلترtextAlign: TextAlign.right تم اضافة
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text(")"كتابي اكاديمية,
leading: IconButton(
icon: Icon(Icons.menu),
onPressed: () { },
),
),
body:
Column(crossAxisAlignment: CrossAxisAlignment.end,// اظهار على اليمين
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
ت
Text(' ' فلتر علم,
textAlign: TextAlign.right, // اتجاه النص
style: TextStyle(
fontSize: 48.0,
color: Colors.deepOrange,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
),
),
Text(' ' عثمان عيدالرحمن,
style: TextStyle(
fontSize: 48.0,
color: Colors.lightGreen,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
),
),
Text(' ' كتابي اكاديمية,
style: TextStyle(
fontSize: 48.0,
color: Colors.indigo,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
),
),
Padding(padding: EdgeInsets.all(16.0),),
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
floatingActionButton: FloatingActionButton(
onPressed: () {print("playing ...");},
child: Icon(Icons.play_arrow),
// backgroundColor: Colors.lightGreen.shade100,// تعطيل اللون
),
),
);
}
}
المخرج
مثال ()7
////////////////////////////////////////////////////////////////////
floatingActionButtonLocation:
FloatingActionButtonLocation.endDocked,
floatingActionButton: FloatingActionButton(
onPressed: () {print("playing ...");},
child: Icon(Icons.play_arrow),
),
),
);
}
}
المخرج
:عند الضغط على الزر العائم تظهر رسالة في الكونسول كما يلي
مالحظة
'fontFamily: 'Arial,
fontFamily: 'Andalus',
الخطوات
بعدها يمكنك اشتخدام الخطوط داخل تطبيقك باالسماء التي سميتها بعا في pubspec.yaml
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text(")"كتابي اكاديمية,
leading: IconButton(
icon: Icon(Icons.menu),
onPressed: () { },
),
),
body:
Column(crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
///////// 01
عت
Text(' ' فلتر لم,
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Andalus1',
fontSize: 62.0,
color: Colors.deepOrange,
),
/////////// 02
),
Text(' ' عثمان عيدالرحمن,
style: TextStyle(
fontFamily: 'Andalus1',
fontSize: 62.0,
color: Colors.lightGreen,
),
),
/////////////// 03
Image(image: AssetImage('images/ka.png'),
),
],
),
////////////////////////////////////////////////////////////////////
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
floatingActionButton: FloatingActionButton(
onPressed: () {print("playing ...");},
child: Icon(Icons.play_arrow),
),
),
);
}
}
المخرج
تم تغيير حجم الخط الى ،22واستخدام الخط الجديد الذي وضعه في التطبيق (وهو االندلس) وتم تسميته
Andalus1في المل pubspec.taml.
تنبيه
المراجع
Beginning Flutter, a hands on guide to app development, Marco L.
Napoli, 2020, Wiley & Sons, Inc.
ويدجيت النموذج
Form Widget
.1..1 .1ويدجيت النموذج ()Form
جميع ويدجيت النموذج هو ويدجيت غير مرئي .هذا يعني أنك لن تراه أبدًا .والغرض الوحيد منه هو التفا
مدخالته ،وبالتالي تجميعها -وبياناتها -في وحدة واحدة .يفعل ذلك باستخدام مفتاح (إذا قررت استخدام نموذج ،فأنت
بحاجة إلى مفتاح عالمي ( GlobalKeyمن النوع )) FormState
(Form
مفتاح النموذج key: _key, //
التحقق االوتوماتيكي مفعل autovalidate: true, //
تضيف هنا حقول النموذج child: //
),
),
خصائص النموذج
تاحذ utovalidateفيمة منطقية ،اذا كانت Trueتعني ان التحقق شغال ويعمل مع اي تغيير يحدث في
اي حقل من حقول المنوذج ،اذا كانت ، Falseفهذا يعني انه عليك القيام بالتحقق يدويا (بكود تكتبه انت)
المفتاح (سميناه _keyفي المثال السابق) ،لديه خاصية currentStateالتي لديها الدوال التالية
: save() .1يحفظ جميع الحقول التي بداخل النموذج عن طريق استدعاء onSavedكل حقل
(لكل حقل onSavedخاصة به)
: validate() .0تنفيذ الدالة validatorلكل حقل (حبث يحتوي كل حقل على validator
خاصة به)
:reset() .3إعادة تعيين كل حقل داخل النموذج إلى القيمة األولية الخاصة به
عند استدعاء إحدى هذه الدوال الثالثة اعاله على ، FormStateفإنه يكرر الحقول الداخلية ويستدعي
تلك الدوال في كل منها .استدعاء واحد على مستوى النموذج يشغلها كلها .
االمر:
)(If _key.currentState.save
للحقل.validator تستدعاءvalidate() بنفس الطريقة فان، للحقلonSaved يستدعي
FormField الويدجيت.1..1
) والتحقق من صحةreset( ) وإعادة التعيينsave( الغرض االساسي لهذه الويدجيت هو توفير الحفظ
.)) االحداث للويدجيت الداخليةvalidator((
ويتم ذلك عن طريق دالة، ليلت (بغا ) ويدجيت االدخالFormField لقد استخدمنا
validator والدالةonSaved ثم بعدها يمكننا اضافة الدالة، builder تسمى
)1( مثال
.في المثال التالي سننشئ نموذج يحتوي على حقل واحد الدخال اسم
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
GlobalKey<FormState> _key = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
//////////////////////////////////////////////
appBar: AppBar(title: Text(")"كتابي اكاديمية,
centerTitle: true,
),
//////////////////////////////////////////////
body:
Form(
key: _key,
autovalidate: true,
child: FormField<String>(
builder: (FormFieldState<String> state) {
return TextField(); // Any field widget like DropDownButton,
// Radio, Checkbox, or Slider.
},
onSaved: (String initialValue) {
// Push values to a repository or something here.
},
validator: (String val) {
// Put validation logic here
},
),
),
),
);
}
}
المخرج
: السطر التاليAppBar اصبح في الوسط الننا اضفنا فيAppBar تالحظ في المخرج ان العنوان في
centerTitle: true,
سيظهر لك الكيبورد ويمكنك اذخال،اذا نقرت بالماوس على حقل النموذج الذي يظهر في الشكل اعاله
soft (بيانات في الحقل (باستخدام الكيبورد العادي او باستخدام الكيبورد الذي ظهر لك في شاشة التطبيق
: كما يلي،))keyboard
التعامل مع TextFieldبشكل مختل .بدالً من لفه ،استبدله بالويدجيت TextFormFieldإذا كنت
تستخدمه داخل نموذج .من السهل الخلط بين هذه الويدجيت مع TextFieldولكنها مختلفة .في األساس
علم فريق Flutterأننا سنحتاج بشكل روتيني إلى عنصر واجهة مستخدم TextFieldباالشتراك مع
عنصر واجهة مستخدم FormFieldلذلك قاموا بإنشاء ةيدجيت TextFormFieldالذي يحتوي على
جميع خصائص TextFieldولكن يضي لها ، validator ،onsavedو reset
مثال ()1
هذا المثال سيعمل كمالثال السابق ،ولكن هنا الكود مختصر ،ويفضل استخدام هذا الويدجبت بدال من
،TextFieldالنك في TextFieldستحتاج الى استخدام FormFieldمعه وكذلك الدالة Build
الضافة ، validator ،onsavedو resetله.
اذن سنستخدم في بقية االمثلة الويدجيت TextFormFieldمع النماذج ،وننصح بذلك ما لم
يكن هنالك شئ يجبرك على استخدام TextField
الدالة :onSaved
يرجى تذكر أن النموذج الخاص بك يحتوي على مفتاح يحتوي على currentStateالتي تحتوي على
الدالة )( ، saveمثال
();_key.currentState.save
ويستدعي بدوره الدالة onSavedلكل FormFieldيحتوي على واحدة (لكل الحقول التي في
النموذج)
المدقق ()validator
ولكن هناك المزيد! إذا قمت بتعيين خاصية التحقق التلقائي للنموذج ( )autovalidateإلى ، true
فورا عندما يقوم المستخدم بإجراء التغييرات.
فسيتحقق فلتر من الصحة ً
.)string( نص/ وترجع سلسلة- القيمة المطلوب التحقق منها- قيمةvalidator ستتلقى كل دالة
) إذا كانت قيمة اإلدخال صحيحة وستكون القيمة المدخلة إذاnull( ستكون القيمة المرجعة قيمة خالية
. هذه السلسلة التي تم إرجاعها هي رسالة الخطأ التي سيظهرها فلتر للمستخدم.كانت غير صحيحة
) لـvalidator( وكتابة مدقق )true ( ) مفعالautovalidate( حيث يتم جعل التحقق التلقائي
: الخاص بكTextFormField
return Form(
autovalidate: true,
child: Container(
TextFormField(
validator: (String val) { // Let's say that an empty value is invalid.
if (val.isEmpty)
return 'We need something to search for';
return null;
},
),
),
);
مثال
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
GlobalKey<FormState> _key = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
//////////////////////////////////////////////
appBar: AppBar(title: Text(")"كتابي اكاديمية,
centerTitle: true,
),
//////////////////////////////////////////////
body:
Form(
key: _key,
autovalidate: true,
child: TextFormField(
onSaved: (String val) {
print('Search Term TextField: form saved $val');
},
validator: (String val) {
if (val.isEmpty)
return 'We need something to search for';
return null;// Put your validation logic here
},
),
),
),
);
}
}
المخرج
أوDropdownButton زر:من الواضح أنه ليس من المنطقي التحقق من الصحة للويدجيتس التالية
. الننا ال تكتب شئ فيهاSlider أوSwitch أوCheckbox أوRadio
.TextFormField يعمل فقط مع.FormField داخلTextField ولكنه ال يعمل مع
عند،تحيانا تحتاج كتابة كود اختبار المدخالت والتحقق من صحتها بعد االنتهاء من ادخال كل البيانات
: للقيام بذلك تحتاج،)submit( الضغط على ور موافق
RaisedButton(
child: const Text('Submit'),
onPressed: () {
// If every field passes validation, run their save methods.
if (_key.currentState.validate()) {
_key.currentState.save();
print('Successfully saved the state.');
}
},
),
3 مثال
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
GlobalKey<FormState> _key = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
//////////////////////////////////////////////////////////////
),
//////////////////////////////////////////////////////////////
RaisedButton(
child: const Text('Submit'),
onPressed: () {
// If every field passes validation, run their save methods.
if (_key.currentState.validate()) {
_key.currentState.save();
print('Successfully saved the state.');
}
},
),
],
),
),
),
),
);
}
}
المخرج
مثال
TextFormField(
decoration: const InputDecoration(labelText: 'Name'),
keyboardType: TextInputType.text,
onSaved: (String val) {
print('Search Term TextField: form saved $val');
},
validator: (value) {
if (value.length < 2) {
return 'Name not long enough';
}
return null;
}
),
المخرج
نالحظ اذا ادخلنا اسم اقل من حرفين او لم ندخل اسم ستعمل الدالة validatorالتس ستختبر طول االسم
،اذا كان اقل من حرفين ستؤجع لنا رسالة خطا ،كما يظهر في المخرج ادناه,
مثال
تطعر رسالة خطأ اذا لم تدخل رقم التلفون ())if (potentialNumber == null
المخرج
استخدام حزمة mailValidatorللتحقق من صحة االيميل
'email_validator: '^1.0.0
:main.dart اضف االمر التالي في بداية
import 'package:email_validator/email_validator.dart';
عندما تبدا بتنفيذ البرنامج سيظهر لك فلتر ان هنالك حزمة ( )dependiciesيجب تحميلها
مثال
في المثال التالي تم اضاف حقل الدخال االيميل والتحقق من صحته باستخدام حزمة
mailValidator
البرنامج كامل (يحتوي نموذج به ثالث حقول (االسم – التلفون – االيميل) وكل حقل يستخدم كيبورد
مخصص لالدخال ،وبع خاصية التحقق من االدخال
;'import 'package:flutter/material.dart
;'import 'package:email_validator/email_validator.dart
;))(void main() => runApp(MyApp
{ class MyApp extends StatelessWidget
;)(>GlobalKey<FormState> _key = GlobalKey<FormState
;String _name
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
//////////////////////////////////////////////
ت
appBar: AppBar(title: Text(" )"فلتر علم كتاب,
centerTitle: true,
),
//////////////////////////////////////////////
body:
Container(
child: Form(
key: _key,
autovalidate:false,
child: Column(children: <Widget>[
TextFormField(
decoration: const InputDecoration(labelText: 'Name'),
keyboardType: TextInputType.text,
onSaved: (String val) {
_name = val;
print('Search Term TextField: form saved $val'+ _name);
},
validator: (value) {
if (value.length < 2) {
return 'Name not long enough';
}
return null;
}
),
///////////////////////////////////////////////
TextFormField(
decoration: const InputDecoration(labelText: 'Mobile'),
keyboardType: TextInputType.phone,
validator: (value) {
var potentialNumber = int.tryParse(value);
if (potentialNumber == null) {
return 'Enter a phone number';
}
return null;
},
),
//////////////////////////////////////////////////////////////
TextFormField(
decoration: const InputDecoration(labelText: 'Email'),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (!EmailValidator.validate(value)) {
return 'Please enter a valid email';
}
return null;
},
),
///////////////////////////////////////////////////////////////
RaisedButton(
child: const Text('Submit'),
onPressed: () {
// If every field passes validation, run their save methods.
{ ))(if (_key.currentState.validate
;)(_key.currentState.save
;)'print('Successfully saved the state.
}
},
),
],
),
),
),
),
;)
}
}
لبمخرج
عند الضغط على االسم سيظهر لك الكيبورد المناسب وسيتم التحقق من االسم ،اذا كان فارغا او اقل من
حرفين ستظهر لك رسالة خطأ
عند الضغط على حقل التلفون سيظهر لك كيبورد لالرقام فقط زاذا لم تدخل رقم تلفون ستظهر رسالة
خطأ
عند الشغط على حقل االيميل سيظهر كيبورد مناسب الدخال االيميل به عالمة (@) ،واذا لم تدخل ايميل
صحيح ستظهر لك رسالة خطأ
المراجع
Beginning App Development with Flutter, Create Cross-Platform Mobile Apps, Rap Payne, 2019
How to Make Email Validation in Flutter – Using Email Validator Library, Rajat
Palankar , March 18, 2020, https://protocoderspoint.com/email-validation-in-flutter-
using-email-validator-library/