با سلام و عرض ادب
در این مقاله آموزشی قصد داریم در مورد مفاهیم کلی مینی فریمورک GetX به همراه مثال های کوچک برای درک مطلب بهتر،صحبت کنیم.
با من همراه باشید.
معمولا بیشتر افراد GetX رو به عنوان پکیجی برای مدیریت وضعیت(State Management) برنامه می شناسند،درصورتی که GetX یک مینی فریمورک هست که به غیر از State Management در برنامه، کاربردهای مهم دیگه ای رو داره که در ادامه مطلب در مورد اون ها صحبت میکنیم.
مینی فریمورک GetX چه مزایایی داره که باعث میشه اون رو نسبت به سایر رقبا متمایز کنه؟
۱- باعث افزایش کارایی(Performance) میشه، به این علت که هدف ساخت این مینی فریمورک بر این بوده که کمترین استفاده از منابع(Resource) رو داشته باشه و همین مورد، علتی هست برای افزایش Performance برنامه، که توسعه دهندگان تونستند به خوبی این کار رو انجام بدن.
دربیشتر فریمورک ها کنترلر در مموری میمونه و ما باید حتما در متد dispose کنترلر خودمون رو ببندیم و درصورت فراموش کردن این مورد مشکل اشفال کردن حافظه به وجود میاد که در GetX به صورت اتوماتیک این کار انجام میشه و از مشکلات احتمالی جلوگیری میشه.
۲- به خاطر syntax ساده کدها،کار توسعه دهنده آسان تر میشه و به طور کلی بهره وری رو افزایش میده .
و مزایای دیگری که میتونید در موردشون بیشتر مطالعه کنید.
خوب حالا که مزایاشو بررسی کردیم میریم سراغ ویژگی های مختلف این مینی فریمورک:
۱- اولین کاربردش این هست به عنوان Route Management استفاده میشه و جابه جایی بین صفحات مختلف رو با ساختار بسیار ساده و با کارایی بالا انجام میده به مثال پایین توجه کنید(قصد داریم از یک صفحه به صفحه دیگه بریم)
کد در حالت عادی:
Navigator.push( context, MaterialPageRoute(builder: (context) => const SecondRoute()), );
کد وقتی از GetX استفاده میکنیم:
Get.to(SecondRoute());
به همین سادگی تونستیم از یک صفحه به صفحه دیگه بریم.البته صرفا اینجا هدف آشنایی با کاربردها هست در ادامه یک مثال کاربردی در محیط برنامه نویسی میزنیم.
۲- به عنوان Dependency Injection از اون استفاده میکنیم بدون نیاز به استفاده از Context:
مثلا وقتی بخوایم در صفحات مختلف برنامه خودمون، از همون نمونه ای که در صفحه اصلی برنامه از کلاس خاصی مثل Api Provider گرفتیم استفاده کنیم، فقط کافیه در صفحه دیگه با استفاده از دستور GetX.find اون نمونه اولی رو که ساختیم رو داخل متغییر بریزیم و از اون استفاده کنیم،برای درک خیلی بهتر در ادامه در قالب مثال توضیح میدم.
۳- به عنوان StateManagement : به صورت خیلی ساده توضیح بدم مثلا ما داخل برنامه اینستاگرام هستیم و یک شخص استوری جدیدی قرار میده و همون لحظه صفحه ما اپدیت میشه و استوری این شخص رو مشاهده میکنیم(بدون اینکه از برنامه خارج بشیم و دوباره وارد بشیم)یک state یا وضعیت جدید رخ میده و اینجاست که state management روی کار میاد و مدیریت state های برنامه رو به عهده میگیره و بدون این که کار خاصی انجام بدیم Ui مارو اپدیت میکنه.
۴-به جز سه تا کار بالا که درموردشون توضیح دادیم چندیدن کار دیگه هم انجام میده که به طور خلاصه توی تصویر زیر میتونید مشاهده کنید.
برای مثال عوض کردن تم برنامه که حالت دارک باشه یا لایت و موارد دیگه.
برای مثال اگر بخوایم یک alertdialog یا یک snackBar نمایش بدیم از تکه کدهای زیر استفاده میکنیم.
Get.defaultDialog(title:"This is dialog"); get.snackbar("Title","This is getx snackbar");
به صورت کوتاه تر و خوانا تر میتونیم با استفاده از دستورات بالا اسنک بار و دیالوگ در اپلیکیشن خودمون نمایش بدیم.
خوب حالا که درمورد ویژگی های مختلف این مینی فریمورک صحبت کردیم بریم در قالب مثال توضیح بدیم که خیلی بهتر برای ما مطلب روشن بشه.
ابتدا یک پروژه جدید میسازیم به اسم learngetx و ساختار پوشه lib ما به شکل زیر هست.
یک دایرکتوری به اسم pages که شامل home و detail هست و هرکدوم از این دایرکتوری ها دوتا دایرکتوری زیرمجموعه دارن به اسم view,controller .
حالا در این لینک میتونید وارد صفحه مربوط به فریمورک GetX بشید و اخرین ورژن اون رو در فایل pubspec.yaml قرار بدین.
dependencies:
get: ^4.6.5
بعد از انجام این کار ما در قسمت view صفحه main خودمون بدین شکل یک کلاس جدید میسازیم :
در کلاس بالا یک Text ساده داریم و یک Button که وقتی دکمه رو لمس کردیم باید به صفحه جزئیات بریم.
پیاده سازی صفحه جزئیات ما هم به شکل زیرهست.
یک AppBar داره با یک دکمه که وقتی لمسش کنیم باید به صفحه قبل برگردیم.
برای جابه جایی بین صفحاتمون اولین کاری که باید انجام بدیم این هست که در کلاس main اصلی برنامه به جای MaterialApp از GetMaterialApp استفاده کنیم.شکل زیر رو مشاهده بفرمایید.
بعد در متد on press دکمه خودمون این خط کد رو اضافه میکنیم.
Get.to(const DetailScreen());
و وقتی دکمه رو لمس میکنیم به صفحه جزئیات میریم.
به همین سادگی ما تونستیم از صفحه home به صفحه detail بریم.
خوب اگه بخوایم از صفحه detail با استفاده از button ای که در appBar تعریف کردیم به صفحه home خودمون برگردیم چه کاری انجام میدیم؟
کافیه فقط از این کد استفاده کنیم.
Get.back();
یک کد دیگه هم هست که با استفاده از اون مطمئن میشیم button ما غیرفعال هست و کاری انجام نمیده.
Get.off();
به همین راحتی ما میتونیم بین صفحات مختلف جابه جا بشیم ،اما همون طور که میدونید پیاده کردن مبحث روتینگ و جابه جایی بین صفحات به شکل های مختلفی صورت میگیره،شما ممکنه قبلا با این روش آشنا شده باشید.
شکل زیر رو مشاهده کنید.
در شکل بالا مشاهده میکنید ما در کلاس main برنامه به هر صفحه ای میخوایم navigate کنیم،یک نام اختصاص میدیم و دیگه به جای این که مستقیم اسم کلاس رو پاس بدیم،نامی که اختصاص دادیم رو پاس میدیم.باعث میشه مدیریت روت های ما خیلی بهتر بشه و سازماندهی تر باشه کدهای ما.
حالا در getX به شکل زیر پیاده میشه:
حالا به جای تکه کد Get.to(const DetailScreen()) برای رفتن به صفحه دیگه از کد زیر استفاده میکنیم.
Get.toNamed("/detail");
به همین راحتی ما میتونیم از GetX برای بحث Routing در برنامه خودمون استفاده کنیم،که باعث میشه از نوشتن کدهای زیاد جلوگیری بشه و همین مسئله باعث خوانایی بهتر کد میشه.
خوب قبل از اینکه بریم سراغ بحث Dependency Management ابتدا یک پکیج جدید به اسم service میسازیم و در داخلش یک کلاس apiservice به شکل زیر میسازیم.
و محتویات کلاس api_service ما هم بدین شکل هست.
ما قرار نیست توی کلاسمون دیتای واقعی رو از اینترنت بگیریم،چون اینجا بیشتر هدف ما یادگیری مفاهیم اصلی هست. کلاس ما شامل یک متد هست که یک text رو برمیگردونه و یک متغییر به نام value.
مبحث Dependency Management در فلاتر:
مینی فریمورک GetX راه آسون و ساده ای رو برای مدیریت Dependency ها و inject کردن dependency ها فراهم کرده بدون نیاز به استفاده از Context.
و به ما کمک میکنه که نمونه یا Instance که از کلاس خاصی مثل ApiProvider گرفتیم رو در صفحات دیگه هم استفاده کنیم، بدون اینکه نیاز باشه مجدد از کلاس ApiProvider نمونه بگیریم و در کل برنامه و کلاس های مختلف از همون یک نمونه اولیه استفاده میکنیم.
وقتی برنامه ما بزرگ میشه این کار باعث میشه مطمئن بشیم در کل برنامه فقط یک نمونه داریم از کلاس داریم وهمین باعث جلوگیری از بروز خیلی از مشکلات کمبود حافظه و ... میشه.
برای درک بهتر در قالب مثال ادامه نوشته رو مطالعه کنید.
تصویر زیر رو مشاهده کنید(به فلش ها توجه کنید)
به کدهای قبلی خودمون فقط دو خط اضافه کردیم که در بالا با فلش مشخص شدن.
خط اول ما یک متغیر به نام apiService تعریف کردیم و با استفاده از دستور get.put کلاس ApiService خودمون رو به این کلاس home برنامه inject کردیم.
و همون طور که مشاهده میکنید در Button گفتیم که متد fetchTextFromApi ما رو پرینت بگیر که با فلش سوم مشخص کردیم و وقتی دکمه رو لمس میکنیم این پیغام رو به ما نمایش میده.
خوب تا حالا کار خاصی انجام ندادیم ،قدرت GetX اینجا هست که ما میخوایم از همین نمونه در صفحه detail هم استفاده کنیم،به تصویر پایین توجه کنید.
ما در صفحه detail یک متغییر ساختیم به اسم apiService و با استفاده از Get.find همون نمونه قبلی مارو هرکجای برنامه گرفته باشیم پیدا میکنه و در داخل این متغییر قرار میده و طبق مثال قبل وقتی دکمه رو لمس میکنیم اون پیغام رو در خروجی نمایش میده.(توجه کنید که ما در این صفحه نمونه جدید نساختیم از کلاس ApiService و از همون نمونه اولی استفاده کردیم)
به همین سادگی ما عملیات Dependency Injection رو در کلاس خودمون انجام دادیم.
برای توضیح این قسمت ما از یک شمارنده ساده استفاده میکنیم که شامل یک Text و دو عدد Button هست برای افزایش و کاهش عددمون،Ui خودمون رو به شکل زیر Update میکنیم:
میدونم جای دکمه ها بهتره عوض بشه و مثبت بره اونطرف ولی به بزرگی خودتون ببخشید D:
خوب الان ما باید یک کلاس جدید در پکیجی که قبلا ساختیم به نام Controller در صفحه home اضافه کنیم که این محتویات کلاس به شکل زیر هست.
به ازای هر صفحه ای که داریم یک کلاس کنترلر با نام دلخواه میسازیم و Extends میکنیم GetxController رو که کلاس خود فریمورک هست، توضیح ساده کلاس این هست که با استفاده از اون میتونیم متغییرها و متدهایی که ساختیم رو کنترل کنیم .
خوب ما اینجا یه متغییر به اسم count ساختیم و دوتا متد که یکیشون به عدد اضافه میکنه و یکیشون کم میکنه عدد رو که قراره از این متد ها در Button های خودمون استفاده کنیم.
نکته مهم وجود obs. بعد از مقدار متغیر count ما هست که مخفف Observable هست که استفاده از دستور باعث میشه هر زمان که متغیر ما تغیری کرد ما بتونیم در جایی که داریم از اون استفاده میکنیم به این متغیر listen کنیم یا گوش فرا بدیم و مقدارمون در Ui تغییر کنه.
مرحله بعد در قسمت Build باید controller خودمون رو inject کنیم،همون طور که در بالا در موردش صحبت کردیم.
خوب حالا باید text و Button هامون رو اپدیت کنیم که وقتی دکمه ها رو لمس میکنیم ،مقدار Text امون تغییر کنه:
۴ خط کد به کدهای قبلیم اضافه کردیم که با فلش مشخص کردم.
برای این که Text ما متوجه تغییر عدد داخل متغیر count ما بشه و خود به خود Ui ما اپدیت بشه باید Text خودمون رو در داخل ویجتی به اسم Obx قرار بدیم که همون Observable در GetX هست و وقتی عدد ما تغییر میکنه عدد داخل Text مارو Update میکنه.
و در داخل Button ها هم متد Increment و Decrement رو با استفاده از homeController فراخوانی کردیم.
و عدد ما کم یا اضافه میشه با استفاده از این Button ها.
خوب الان ما میخوایم توی صفحه detail خودمون به مقدار update شده متغیر خودمون دسترسی داشته باشیم.مثلا عدد ما الان توی صفحه اصلی ۴ هست و توی details هم باید همین رو نشون بده.
اگر با Bloc کار کرده باشین میدونین انجام این کار یه خورده پیچیده هست ولی GetX خیلی راحت و آسون این کارو برای ما انجام میده.فقط با دو سه خط کد
همون طور که مشاهده کردید فقط با استفاده از متد Get.find اون نمونه ای که قبلا گرفتیم رو فراخوانی میکنیم و Text رو نمایش میدیم.الان اگر من در صفحه اصلی عدد رو تا ۱۰ بالا ببرم در این صفحه هم عدد ۱۰ رو نمایش میده.
مفهوم binding باعث میشه که ما تمام inject هامون رو در این کلاس خاص تعریف کنیم و کد ما خواناتر میشه و بعدا خیلی راحت متوجه میشیم که inject ها و state هامون مربوط به چه صفحه ای هستن.
برای درک بهتر با من همراه باشید.
ما یک پکیج جدید در پکیج home خودمون میسازیم به اسم binding و در داخل اون کلاسhome_binding.dart رو میسازیم.
و ما باید inject هایی که در کلاس main داریم رو در این کلاس اضافه کنیم.
محتویات کلاس home_binding ما به شکل زیر هست.
و در صفحه main امون به جای دو خط inject مثل شکل زیر از find استفاده میکنیم.
خطوطی که کامنت شده رو حذف میکنیم و به جاش از find استفاده میکنیم و خود find جست و جو میکنه و از داخل کلاس binding کلاس هایی که inject کردیم رو پیدا میکنه.
تنها کاری که باید بکنیم این هست که در روت خودمون بگیم که homeBinding مربوط به کدوم روت هست.
به شکل زیر توجه کنید.
و این کار ما باعث میشه کد خیلی خوانا تر بشه.همین کار رو هم میتونیم برای صفحه detail انجام بدیم که خیلی ساده هست و من انجامش میدم و در صفحه گیت هاب خودم قرار میدم از اینجا میتونید مشاهده کنید.
تا حد ممکن سعی کردم ساده و مفید و خلاصه توضیح بدم.
امیدوارم که مطلب مورد پسندتون قرارگرفته باشه.
اینجا هم آموزش پیاده سازی دوتا اپ کامل تر رو با استفاده از GetX میتونید،مشاهده کنید.
https://www.youtube.com/watch?v=apPH1CCOtKQ
https://www.youtube.com/watch?v=tNGfVp4KY2g&t=4s
لینک گیت هاب اپلیکیشن:
https://github.com/iManYarahmadi/LearnGetX
موفق باشید
یاعلی