آموزش فلاتر در یک روز

دوره آموزش دارت و فلاتر(توجه شود این مقاله در حال تکمیل است و به مرور مطالب اضافه می شود.)با سلام و عرض خسته نباشید، توی این مقاله قصد داریم به برسی زبان Dart و فریمورک Flutter بپردازیم. برای اینکه بتوانیم کد های فلاتر را اجرا کنیم نیازمندیم تا SDK فلاتر و اندروید استودیو را نصب کنیم. برای اینکار می توانید از لینک زیر استفاده کنید:Flutter.dev/docs/get-started/install/حال قبل از اینکه به سراغ فلاتر برویم با مقدمات زبان Dart آشنا می شویم. دارت یک زبان سطح بالا می باشد که syntax مشابه java و C# دارد ولی سطح بالاتر نسبت به آن دو می باشد (بر خلاف آن دو مفسری است نه کامپایلری). بدون اینکه درگیری مقدمات شویم به برسی خود زبان می رویم. در دارت لازم است کد ها را در داخل یک تابع اصلی (تابع main) قرار دهیم که به ترتیب زیر تعریف می شود:void main () {// Your codes here}همچنین متغیر ها به ترتیب زیر تعریف می شود. توجه شود که از تابع print می توان برای نمایش داده ها در ترمینال استفاده کرد:void main () {int a = 12; // Integer number print(a);double b = 12.2; // Float numberString s = &quotahmad&quot // String , notice that &quotS&quot is capitalbool c = true; // Boolean}همچنین یک نوع متغیر به نام لیست وجود دارد که می توانند تعداد زیادی داده در خود ذخیره کنند. در این نوع داده لیست همانند پایتون ضروری ندارد که نوع اعضا یکی باشد و می تواند متفاوت باشند. به مثال زیر توجه کنید:List l = [ 10 , 1.34 , false , 'ali' ];لازم به ذکر است ایندکس لیست ها از عدد 0 شروع می شود و برای دسترسی به هر عضو از لیست از براکت کمک می گیریمl[0] // => 10 l[1] // => 1.34 l[2] // => falseهمچنین در صورتیکه بخواهیم برای داده های یک لیست نوع داده مشخصی را تعیین کنیم کافی است در داخل براکت های <> نوع داده های لیست را مشخص کنیم :List<String> i = ['ahmad' , 'farhad' , 'ali'];همچنین می توان به کمک دستور var متغیر ها را بدون نیاز به معرفی تایپ آنها تعریف کرد. فقط نکته ای که در مورد این نوع تعریف کردن هست این است که متغیر تعریف شده دیگر قابلیت تغییر تایپ در ادامه برنامه را ندارد (نوع متغیر در ابتدا کار با توجه به مقدار اولیه تعیین می شود.) مثلا اگر ابتدا به صورت int باشد تا پایان برنامه نیز به همین نوع int باقی می ماند و در صورت تغییر با ارور مواجه می شویم:var A = 12.3; // doubleحال که کمی با ساختار ابتدایی دارت و فلاتر آشنا شدید، مطالب را کمی منسجم تر دنبال می کنیم. فهرست مطالب به ترتیب لیست زیر ادامه پیدا می کند:شرطحلقهتابعدستور شرط ifدستور شرط if یکی از دستوراتی است که به کمک آن می توان کنترل جریان در برنامه انجام داد و بسته به برقرار بودن شرایط مختلف، کامند های خاصی را در برنامه اجرا کرد. ساختار کلی این دستور شرط به ترتیب زیر می باشد که قسمت میانه ای (یعنی else if) می تواند چند بار یا هیچ بار تکرار شود ?:void main() { if(condition1) { // run commands if conditon1 is true } else if (condition2) { // run command if condition2 is true } else { // run this commnad if none of them was true } }در دستور بالا زمانی که شرایط برقرار باشند، بلوک مربوطه اجرا می شود. برخی از عملگرهای منطقی که ممکن است به کارتان بیایند عبارتند از :عملگر اشتراک یا "وَ" که با && نمایش داده می شودعملگرد اجتماع یا "یا" که با || نمایش داده می شودعملکر انفعال یا "نه" که ! نمایش داده می شودتعدادی دیگر عملگر نیز وجود دارد که می توانید داکیومنت دارت آنها را مطالعه کنید. یک دستور شرطی دیگر نیز وجود دارد که برای حالاتی که شرط ها زیاد هستند مناسب می باشد. این دستور switch نام دارد و به صورت زیر استفاده می شود.void main() { var brandName = &quotSony&quot switch (brandName) { case &quotSony&quot: print(&quotThe price is : 1000&quot); break; case &quotSamsung&quot: print(&quotThe price is : 2000&quot); break; case &quotApple&quot: print(&quotThe price is : 3000&quot); break; default : print(&quotThe price is un-known&quot); } }در مثال بالا بسته به اینکه نام برند چه باشد، قیمت در ترمینال چاپ می شود.حلقه هاهر گاه بخواهیم در برنامه بنابر شرایطی کاری را به صورت تکراری انجام دهیم از حلقه ها استفاده می کنیم. می توان به کمک دستور های مختلف حلقه ها را ایجاد کرد. اولین دستور ایجاد حلقه، دستور for می باشد که ساختار آن به ترتیب زیر می باشد:for( int i=0 ; i < 10 ; i++ ) { // Some commands that should run in a loop print(i); }که در حلقه for ما ابتدای کار نیاز داریم تا اولا متغییر شمارنده را تعیین کنیم، ثالثا شرط پایان دهنده حلقه (شرطی که تا زمانیکه برقرار باشد حلقه اجرا می شود.) مشخص کنیم و سادسا در صورتی که شمارنده عددی تعیین می کنیم پله را نیز مشخص کنیم. برای مثال حلقه بالا برای ما از صفر تا عدد 9 را در ترمینال چاپ می کند. همچنین در صورتی که نیاز باشد می توانیم داخل لیست ها نیز از حلقه استفاده کنیم، مانند حلقه زیر:var names = [&quotahmad&quot, &quotfarhad&quot, &quotali&quot , &quotkarim&quot, &quotsina&quot]; for (var name in names) { print(name); }که در حلقه بالا لیست نام های تعریف شده در لیست برای ما در ترمینال چاپ می شود. یک دستور حلقه دیگر نیز داریم که تا زمانی که شرطی برقرار باشد برای ما یک لوپ را تکرار می کند. اسم این حلقه while می باشد که در مثال پایین می توانید کاربرد آنرا مشاهده کنید. (شرط حلقه => تازمانی که i کوچکتر از 10 می باشد)void main() { var i = 0; while (i < 10) { print(i); i++; } }که در مثال بالا مادامی که i کوچکتر از 10 باشد، در ترمینال اعداد برای ما از صفر چاپ می شود؛ یعنی در ترمینال از 0 تا 9 برای ما چاپ می شود.تابعتابع دستوری است که می تواند چند یا هیچ متغیری را در ورودی از ما دریافت کند و در خروجی یک یا هیچ مقداری را بازگرداند، مثلا نمونه بارز تابع، همان تابع main می باشد که دستورات اصلی برنامه در آن اجرا می شود و به صورت زیر است:void main() { // Main codes }توجه شود برای تعریف تابع باید نوع تابع را بسته به ورودی void، int, double, String و ... مشخص شود. نمونه تابع دیگر را می توانید در مثال زیر مشاهده نمایید:void main() { // Main codes var brand = &quotSony&quot int price = getPrice(brand); print(price); } int getPrice(String brandName) { switch (brandName) { case &quotSony&quot: return 1000; case &quotSamsung&quot: return 2000; case &quotApple&quot: return 3000; default: return -1; } }در مثال بالا تابع در ورودی از ما نام برند را می گیرد و بسته به آن قیمت را به ما می دهد. اکنون با مفاهیم پایه ای و ابتدایی زبان فلاتر آشنا شدید در ادامه به برسی شی گرایی در زبان دارت می پردازیم.کلاس و شیء در زبان دارتدر زبان های برنامه نویسی کلاس ها جزء مفاهیم پیشرفته هستند. کلاس در واقع یک نقشه می باشد و شیء یک مدل پیاده سازی شده از آن نقشه می باشد.برای فرض یک شرکت خودرو سازی را فرض کنید؛ در شرکت خودروسازی نقشه خودرو در واقع همان کلاس می باشد و خودرو یک شیء ایجاد شده از آن کلاس است. از شیء گرایی بدین منظور استفاده می شود تا بتوان برنامه های تمیزتر و کاراتر ایجاد کرد و نیاز نباشد برای هر تغییر کوچک در روند برنامه باگ های زیادی ایجاد شود. کلاس ها در زبان دارت به شکل زیر تعریف می شوند:void main() {User ahmad = User(21, 'absoftcompany@gmail.com');print(ahmad.email) // Access the object propertyahmad.login(); // Accessing the object property}Class User {// propertiesint age; String email;// Constructor methodUser( int a, String e) {this.age = a;this.email = e;}// Simple methodsvoid login( ) {print('User Logined!');}}در کد بالا یک کلاس با نام User ایجاد شده که دارای پروپرتی ها سن و ایمیل می باشد (متغیر در کلاس همان پروپرتی نامیده می شود.) و همچنین یک متد سازنده دارد که به هنگام تعریف شیء بتوان برخی از پروپرتی های دلخواه را مقدار دهی کرد، همچنین یک متد (توابع در کلاس متد نامیده می شوند.) لاگین تعریف شده که یک نوشته را در خروجی چاپ می کند. به علاوه یک شی به نام ahmad از آن ایجاد شده است که می توانید در کد بالا مشاهده کنید.بریم سراغ خود فلاتراکنون که با مفاهیم ابتدایی زبان دارت آشنا شدید می توانیم به سراغ استفاده از فلاتر می رویم. پس از نصب فلاتر و اندروید استودیو طبق داکیومنت فلاتر که زودتر گفته شد، یک اپلیکیشن فلاتر بر روی اندروید استودیو باز کنید (حتما پلاگین مربوط به فلاتر و دارت را در اندروید استودیو نصب کنید.) و نام و دایرکتوری دلخواه را به ویزارد اندروید استودیو بدهید تا اپ را برای شما ایجاد کند. (در این مرحله ارتباط با اینترنت نیاز است و حتما به یاد داشته باشید که وی پی ان روشن باشد چون سورس برخی از کتابخانه ها روی کلواد گوگل قرار دارد و برای ایران تحریم است.?) فلاتر یک فریمورک برای زبان دارت می باشد که پر از ویجت ها می باشد و در واقع ما به کمک فریمورک فلاتر رابط کاربری اپ مان را طراحی می کنیم. در این فریمورک ویجت های گوناگونی از جمله نوبار، دکمه و .... وجود دارد که در ادامه آنها را برسی می کنیم. به کمک فلاتر می توانیم از استاندارد های گوناگون طراحی به سادگی استفاده کنیم. یکی از استاندارد هایی که برای طراحی رابط کاربری موبایل عرضه شده است، رابط کاربری متریال دیزان می باشد که توسط گوگل ارایه شده است. خوشبختانه فریمورک فلاتر ویجت های مربوط به این نوع از طراحی را به صورت پیشفرض پشتیبانی می کند و نیاز نیست از صفر ویجت های متریال را دستی ایجاد کنیم. در ادامه کتابخانه مربوط به این ویجت ها را به برنامه main.dart اضافه کرده و از آن در ایجاد برنامه بهره می بریم. (یادم رفت بگم که با دستور import میشه کتابخونه و سایر فایل های فلاتر را به صورت ماژول وار به پروژه اضافه کرد ? )import 'package:flutter/material.dart'; void main() { runApp( MaterialApp( home: Text('hello world'), )); }که در برنامه بالا نکات زیر حائز اهمیت است:توسط دستور runApp یک کلاس که شامل ویجت ها می باشد اجرا می شود.کلاس MaterialApp از کتابخانه ادد شده گرفته شده و قرار است با استفاده از پروپورتی های آن ظاهر اپ را شکل دهیم. در اینجا در پروپرتی home مثلا گفته شده که با یک ویجت متن نمایش داده شود.همچنین پروپرتی ها با کاما (,) از هم جدا می شوند.خروجی برنامه را می توانید در برنامه زیر مشاهده کنید.خروجی کد در امولاتور اندرویددر ادامه برنامه بالا را به کمک ویجت های بیشتری ایجاد می کنیم تا خروجی بهتری بگیریم. کتابخانه متریال دیزاین یک ویجت به نام scaffold ارایه کرده که می توان به کمک کن سر و شکل برنامه شکیل تر و بر مبنای استاندارد ها طراحی کرد. در کل زیر می توانید نحوه استفاده از این ویجت و ویجت های زیر مجموعه آنرا مشاهده کنید:import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Demo App'), centerTitle: true, ), body: Center( child: Text(&quotHello World Material Design&quot), ), floatingActionButton: FloatingActionButton( child: Text('Click'), ), ), )); }در کد بالا نکات زیر مطرح است:ویجت scaffold رابط کاربری اپ را به بخش های مختلف appBar, body, ... تقسیم می کند.به هر کدام از بخش ها می توان یک ویجت اختصاص داد و همچنین پروپرتی های زیادی دارد که به آنها می توان مقادیر و یا ویجت دیگری اختصاص داد.یک ویجت به نام Center وجود دارد که با اختصاص هر ویجت به پروپرتی child آن، ویجت ارایه داده شده در مرکز قرار می گیرید.خروجی کد بالا را می توانید در شکل پایین مشاهده نمایید:خروجی سلام بر دنیا با استفاده از ویجت اسکفولد متریال اپ فلاتربرای مشاهده جزئیات بیشتر در مورد ویجت اسکفولد می توانید به لینک این ویجت در داکیومنت فلاتر مراجعه نمایید: https://api.flutter.dev/flutter/material/Scaffold-class.htmlحال کمی استایل برنامه بالا را عوض می کنیم، مثلا رنگ ها یا فونت و ... را. استایل دهی نیز از طریق پروپرتی های امکان پذیری می باشد.import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Demo App'), centerTitle: true, backgroundColor: Colors.red[600], ), body: Center( child: Text(&quotHello World Material Design&quot, style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, letterSpacing: 2, color: Colors.grey[600], ), ), ), floatingActionButton: FloatingActionButton( onPressed: () {}, child: Text('Click'), backgroundColor: Colors.red[600], ), ), ));در کد بالا نکات زیر مهم هستند:برای مشاهده لیست رنگ های می توانید به سایت material.io مراجعه کنید.برای استایل دادن به ویجت Text از یک ویجت زیر مجموعه TextStyle استفاده می کنیم. (با کلید Control+Q می توانید به لیست پروپرتی های استایل قابل تنظیم دسترسی پیدا کنید.)خروجی کد بالا به شکل زیر می باشد:تغییرات کوچک در استایل اپ برای آشنایی با پروپرتی های استایلدر ادامه یک فونت دلخواه به پروژه اضافه می کنیم. در ابتدا بایت نسخه ttf فونت مدنظر را پیدا کنید، سپس در دایرکتوری اصلی یک پوشه دلخواه مثلا به نام fonts ایجاد کنید و فایل فونت را در آن قرار دهید. سپس در فایل pubspec.yaml بروید و قسمت مربوط به فونت ها را uncomment کنید و یک نام برای فونت انتخاب کنید (بعد از این کد در کد ها مون استفاده می کنیم.) و آدرس آنرا در فایل کانفیگ مشخص کنید. مثلا ما یک فونت فارسی قرار می دهیم. سپس در کد برای نوشته ها fontFamily را روی فونتی که وارد کردیم قرار می دهیم. کد به شرح زیر است:import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( home: Scaffold( appBar: AppBar( title: Text('اپ دمو', style: TextStyle( fontFamily: 'IranYekan', fontWeight: FontWeight.bold ), ), centerTitle: true, backgroundColor: Colors.red[600], ), body: Center( child: Text(&quotسلام دنیا، این یک اپ دمو است&quot, style: TextStyle( fontSize: 20, color: Colors.grey[600], fontFamily: 'IranYekan', ), ), ), floatingActionButton: FloatingActionButton( onPressed: () {}, child: Text('کلیک', style: TextStyle( fontFamily: 'IranYekan', fontWeight: FontWeight.w800 ), ), backgroundColor: Colors.red[600], ), ), )); }همچنین خروجی برنامه نیز به شکل زیر می باشد:خروجی برنامه با فونت و متن فارسیهمچنین یکی از مزایای فلاتر در مقایسه با اپلیکیشن نویسی با کاتلین و سوئیفت این است که شما را قادر می سازد تغییرات را در کسری از ثانیه در امولاتور مشاهده کنید. به این قابلیت Hot Reload می گویند و به صورت پیشفرض فعال است و در صورتی که از statelesswidget استفاده کنید با هربار ذخیره کردن در اندروید استودیو تغییرات برای شما به صورت لایو قابل مشاهده خواهند بود. برای ایجاد کلاس stateless از شورت کد stless استفاده کنید و اینتر بزنید، سپس مطابق کد زیر ویجت های اسکفولد را در داخل کلاس جدید قرار دهید:import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( home: Home() )); } class Home extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('اپ دمو', style: TextStyle( fontFamily: 'IranYekan', fontWeight: FontWeight.bold ), ), centerTitle: true, backgroundColor: Colors.red[600], ), body: Center( child: Text(&quotسلام دنیا&quot, style: TextStyle( fontSize: 20, color: Colors.grey[600], fontFamily: 'IranYekan', ), ), ), floatingActionButton: FloatingActionButton( onPressed: () {}, child: Text('کلیک', style: TextStyle( fontFamily: 'IranYekan', fontWeight: FontWeight.w800 ), ), backgroundColor: Colors.red[600], ), ); } }خروجی برنامه همان خروجی قبلی است و اینبار با هر بار سیو کردن تغییرات به صورت لحظه ای می توانید آنرا مشاهده کنید. ادامه بزودی ... تا همینجا رو اگه خوندی و دوست داشتی کامنت بذار و لایک کن ❤