ramin bagherian
ramin bagherian
خواندن ۸ دقیقه·۳ سال پیش

توضیحاتی در مورد microframework GetX در فلاتر

نوشته شخصی " این اولین پست من تو سایت ویرگول هستش و همچنین اولین مقالم امیدوارم که بتونم حق مطلب رو درست ادا کنم "

خب بریم سراغ بحث ...
بیاین ببینیم اصلا GetX چی هست کلا ؟
یا اگه بخوایم ریزتر بشیم state چی هست ؟

با یه مثال شروع کنیم : چه اتفاقی می افته وقتی کلید چراغ خونتون یا اتاقتون رو فشار میدین ؟
خب از دید برنامه نویسی کلید و چراغ UI ما هستن ! و جریان برق logic سناریوی ما هستش و فشار دادن کلید event
وقتی شما کلید رو فشار میدید در واقع وضعیت (state) اون کلید رو از خاموش به روشن و یا برعکس تغییر دادین و این باعث تغییری تو logic شده و state چراغ رو از خاموش به روشن یا برعکس عوض کرده
پس تغییر وضعیت کلید باعث تغییر وضعیت چراغ شده .
تو فلاتر تمام ویجت ها حول محور state میچرخه و هر تغییری که UI به خودش میگیره درواقع state اون UI یا Widget تغییر کرده
مدیریت state یکی از مسائل مهم و البته پیچیده فلاتر به حساب میاد ساده ترین روش برای مدیریت استفاده از متد setState هستش که خب مشکلات خاص خودش رو داره مثل پرفورمنس پایین و فراخوانی متد build
ولی کتابخونه های خوبی برای راحتی کار هستن که از این پیچیدگی تا حد زیادی کم کنن !
مثلا : Proveider , Flutter BloC , Get it , Mobx
و GetX .....

کتابخونه یا همون microframework GetX یکی از معروفترین و ساده ترین های فلاتر هستش ( از نظر من )

که امکانات زیادی داره و فقط state management نیست
سه ستون اصلی GetX :
1 . state management مدیریت وضعیت :
در حالت کلی از دو روش برای مدیریت وضعیت استفاده میکنه اولی متد GetBuilder هستش که ساده ترینش هست و دومی استفاده از وضعیت واکنشی (reactive state) با استفاده از Getx یا Obx هستش که تو این مقاله درمورد هر دو روش صحبت میکنیم .
2 . Route Management مدیریت مسیر :
با GetX میشه بین صحفه های مختلف جابجا شد, SnackBar , Dialog , BottomSheet نمایش داد , و همه این کار هارو بدون نیاز به context انجام داد ( جالب شد نه ؟ D:) البته این مقاله فقط در مورد مدیریت وضعیت با GetX هستش ولی سعی میکنم یه مثال کوچیک در مورد این موارد هم بزنم و اگه این مقاله براتون مفید باشه مقالات بیشتری در این باره بنویسم.
3 . Dependency Management مدیریت وابستگی :
یکی از ساده ترین و قدرتمد ترین راه های مدیریت وابستگی استفاده از controller های GetX هستش که کلا با یک خط کد هندل میشه, و اجازه دسترسی به View رو بدون نیاز به Inherited Widget یا context رو میده, به زبان ساده GetX جلوی تکرار کد رو تا حد قابل قبولی میگیره.

خب حالا بریم یه مثال با کد بزنیم ببینم این گفته ها تو عمل چه شکلی هستش :

قدم اول ساخت یه پروژه خالی هستش که دیگه توضیح نمیدم چجوری اینو همه بلدیم ....

قدم دوم اضافه کردن GetX به پروژه داخل فایل pubspec.yaml هستش از سایت pub.dev آخرین نسخه GetX رو به شکل زیر به پروژه اضافه کنین ( قندشکن لازم دارین این قسمت)


dependencies: flutter: sdk: flutter get: ^4.6.1

(درحال حاضر که من این مطلب رو مینویسم آخرین نسخه از این کتابخونه 4.6.1 هستش)
حالا یا دستور

flutter pub get

رو تو ترمینال بنویسید یا فایل pubspec.yaml رو ( ctrl + s ) ذخیره کنین تا دانلود انجام بشه.

قدم سوم عوض کردن ویجت MaterilApp به GetMaterialApp داخل کلاس main.dart هستش که بعد از اضافه کردن کتابخونه به پروژه در دسترس هست الان

نتونستم با کد باکس خود ویرگول کنار بیام ....
نتونستم با کد باکس خود ویرگول کنار بیام ....

خب تا اینجا یه سری کار های اولیه و ابتدایی بود.
اینجا ما یه ویجت تکس داریم و یک فلوتینگ باتن که قراره با هربار فشار دادن ( همون سناریوی چراغ و کلید که اول گفتم ) مقدار تکس ما رو تغییر بده یا همون state ویجت تکس ما تغییر کنه !
میدونیم که setState هم این کارو برامون انجام میده ولی اضافه بار داره, یعنی تمام ویجت هارو دوباره build میکنه در حالی که ما فقط نیاز داریم که ویجت تکس ما تغییر وضعیت بشه و دوباره ساخته بشه..

خب اول از GetBuilder شروع میکنیم بعد میریم سراغ Obx :

قدم چهارم ساخت یه کلاس کنترولر هستش که از GetxController ارثبری کرده باشه و مقادیری که قراره تغییر کنه رو داخلش تعریف میکنیم

خوب ما اینجا کلاس MyController رو داریم که از کلاس GetxController ارثبری کرده و الان به متد های این کلاس دسترسی داره
یه متغییر از نوع int داریم که مقدار مارو داخل خودش داره و قراره که با هربار کلیک روی دکمه مقدارش تغییر کنه و در نهایت یه getter تعریف کردیم که مقدار رو از این متغییر و کلاس بگیریم ( اجباری برای تعریف getter نیست من از رو عادت این کارو کردم میشه مستقیم مقدار counter رو بگیرین البته دیگه نباید private تعریف بشه تو این حالت )


خب قدم پنجم : تعریف یک تابع هستش که عملیات افزایش رو برامون انجام بده و به ما notify کنه این موضوع رو یا به اصطلاح خبر بده به ویجت های مرتبطش واسه تغییر وضعیت

متد incrementCounter یه متد خیلی سادس که فقط مقدار رو افزایش میده و در آخر هم update رو صدا میزنه.
حالا این update چیکار میکنه رو اینجا نمیشه گفت چون واسه توضیحش لازمه کدهای کلاس main کامل بشه بعد !
پس این متد update رو یادتون نگه دارین تا بعدا برسیم بهش...

قدم ششم : میریم سراغ کلاس main و ادامه کد
ما گفتیم که میخوایم فقط ویجت Text ما تغییر وضعیت داده بشه و بقیه ویجت ها ثابت بمونن, واسه این کار کافیه ویجت Text رو داخل ویجت GetBuilder قرار بدیم و کلاس MyController رو بهش تعریف میکنیم.
GetBuilder داخل خودش متدی داره به نام builder
builder درواقع از ما یه کنترولر میگیره و یه ویجت برمیگردونه که ما کنترولر رو به شکل زیر بهش معرفی کردیم

GetBuilder<MyController> { builder: (_clr){ return Text(' counter ${_clr.getCounter.toString()} ' ); } }

درواقع clr_ نمونه ای از همون کلاس کنترولری هست که ما تعریف کردیم و الان به واسطه اون به مقادیر دسترسی داریم و هر بار که متد update داخل اون کلاس صدازده میشه ویجت یا ویجت های داخل builder باز سازی میشه ولی با مقادیر جدید .

پس حالا فهمیدیم که اون متد update تو کلاس MyController به چه دردی میخوره :)

خب تا اینجا که همه چی اوکی شد .
میریم سراغ دکمه که قرار کار افزایش رو برامون انجام بده

قدم هفتم : برای این کار لازمه که از کنترولر نمونه سازی انجام بدیم ولی به روشی که خود GetX گفته یعنی به شکل زیر :

final _controller = Get.put(MyController());
  • نمونه گیری تو GetX حالت های مختلفی داره که همرو نمشه تو یه مقاله گفت سعی میکنم بعدا درموردش توضیح بدم

حالا ما یه نمونه از کلاس MyController با نام controller_ داریم و مسلما به متد ها هم دسترسی داریم
شاید سوال بشه که چرا مقدار Text رو با همین نمونه که ساختیم عوض نکنیم !
جوابش سادس چون اگه این کار انجام بدیم دیگه state عوض نمیشه و فقط مقدار عوض میشه .. یعنی عملا تو UI چیزی تغییر نمیکنه !
این GetBuilder هستش که state رو تغییر میده .
اگه یادتون باشه ما یه متدی داشتیم به اسم incrementCounter حالا خیلی راحت داخل پراپرتی onPressed دکمه متد رو صدا میزنیم

onPressed: (){ _controller.incrementCounter(); }

خب تبریک میگم شما الان یه state management هر چند خیلی ساده رو پیاده کردید ! :)

خوب بریم سراغ Obx:

روش Obx تقریبا مشابه روش بالاس با یه سری تفاوت های کوچیک ....
بریم سراغش

تو روش Obx ما همون کلاس MyController رو داریم ولی با یه تفاوت تو نوع متغییر ها
متغییر هایی که تو این حالت تعریف میشن از نوع observable هستند و میشه گفت یه حالت استریم دارن ! یعنی دیگه نیازی به متد update نداریم .
میریم سراغ کنترولر و تعریف متغییر

کلمه کلیدی این متغییر ها با Rx شروع میشه و تقریبا همه Data type هارو شامل میشه !
ما اینجا از RxInt استفاده میکنیم چون نوع دادمون عدد صحیح و بعد از مقدار دهی obs که مخفف observable هستش رو به آخر مقدار اضافه میکنیم !
و بعد داخل updateValue عملیات افزایش داده رو انجام میدمیم !
کل کنترولر شد 3 خط جذاب نیست؟ :)

خب بریم سراغ کلاس main :
داخل این کلاس اگه یادتون باشه ما یه ویجت GetBuilder داشتیم دقیقا همون ویجت رو یه Obx تغییر میدیم و builder رو هم حذف میکنیم !
خییییلی جمع و جور ساده :)

Obx ( () Text( &quot counter : ${_controller.counter.value} &quot ) )

کل اون GetBuilder شد این یک خط ولی فراموش نکینن که هنوزم به اون نمونه که از کلاس MyController ساختیم نیاز داریم و باید باشه .
و نکته مهم بعدی اینکه واسه گرفتن مقدار از متغییر های نوع Rx یا observable حتما باید بعد از نام متغییر به value اشاره کنین تا مقدار گرفته بشه ...

_controller.counter.value;

این کلاس main که بجای GetBuilder از Obx استفاده شده .

حالا بیاین با همین روش یه SnackBar نمایش بدیم به کاربر, ببینیم چطور بدون context میشه این کار کرد ؟

سناریو

میخوایم وقتی مقدار counter به 3 رسید یه SnackBar نشون بدیم به کاربر و حالا یه متنی آزمایشی هم داشته باشه
بریم سراغ کنترولر و متد update که به شکل لامبدا نوشتیم.
کلاس Get به صورت پیشفرض متد هایی مثل Get.snackbar( title , description ) که برای ما یه snackBar بدون نیاز به context رو میده و همچنین امکان شخصی سازی هم داره و در کل میتونم بگم که از snackBar که از سمت scaffold میاد خییلی بهتره D:
کلاس کنترولر رو به شکل زیر تغییر میدیم !

همون طور که میبینین داخل متد updateValue با دستور if مقدار counter رو چک میکنیم که اگه به مقدار 3 یا بیشتر رسیده باشه snackBar نمایش داده بشه ...
مقادیر ورودی snackBar که اجباری هستن title و decription هستش و به صورت پیشفرض از سمت بالا ظاهر میشه ولی قابل شخصی سازی هستش و تقریبا میتونین همه قسمت هارو تغییر بدین ...

خب امیدوارم که از این مطلب لذت برده باشید و براتون مفید بوده باشه !
اگه استقبالی بشه سعی میکنم GetX رو به صورت کامل در حد اطلاعاتم توضیح بدم که دوستان علاقه مند بتونن استفاده کنن ...
ممنون از وقتی که گذاشتین برای مطالعه این مقاله
موفق باشید .

flutter
برنامه نویس اندروید ( جاوا یِ سابق, فلاتر الان )
شاید از این پست‌ها خوشتان بیاید