اگر به تازگی شروع به یادگیری فلاتر کردهاید بهتر است با برخی مفاهیم پایه در فلاتر آشنا شوید. حتی اگر برنامهنویسی باتجربه در فلاتر محسوب می شوید، مرور این مفاهیم به درک بهتر شما از این فریم ورک کمک خواهد کرد.
فلاتر کیت توسعهی نرم افزار موبایل است که توسط گوگل برای طراحی اپلیکیشن چند پلتفرمی (اپلیکیشنی که یک کد پایه یکسان دارد اما بر روی پلتفرمهای متفاوت قابل اجرا است) توسعه داده شده است. ویجتها (Widgets) بلاک سازندهی اصلی آن به شمار میروند. اما ویجت چیست؟ در این مقاله به دنبال پاسخ این سوال هستیم.
ویجت فلاتر در واقع کلاسی است که میداند چطور واسط کاربری (User Interface) خود را توصیف کند. اپهای فلاتر مجموعهی بزرگی از ویجتها هستند. از ویجتها نه تنها برای نمایش صریح عناصر بصری (مانند دکمهها و کادرهای متنی)، بلکه برای نمایش عناصر انتزاعی مثل ترازبندی نیز استفاده میشود.
ویجتها چرخهی حیات مخصوص به خود را دارند که دانستن آن به درک عمیق تر فرایندهای پشت صحنه و کشف برخی مشکلات رایج بسیار کمک میکند. اما پیش از آن که با چرخهی حیات ویجتها آشنا شویم، بهتر است برخی مفاهیم پایه را بدانیم. (سعی میکنم در مقالهای دیگر درباره چرخهی حیات ویجتها توضیح دهم.)
درخت ویجت: همانطور که پیش از این اشاره شد، هر اپلیکیشن فلاتر مجموعهای است از ویجتهایی که آن را تشکیل میدهند. هر جنبه از برنامه به کمک ویجت به نمایش در می آید:
همهی ویجتها در مجموعهی ویجتها با گسترش ساختار درختی مرتب می شوند: هر عنصر (گره) می تواند فرزندانش را مشخص کند بنابراین یک رابطهی والد-فرزندی بین آنها برقرار میشود.
ترکیب (Composition): برخلاف دیگر فریم ورکها و زبانهای برنامه نویسی، فلاتر استفاده از ترکیب را بر وراثت ارجحیت می دهد. وقتی که یک عنصر UI جدید میسازید، به جای اینکه آن را زیرنوع عنصری موجود قرار دهد (subtyping)، آن را داخل عنصر دیگری قرار می دهد (wrapping).
برای مثال فرض کنید صفحهای داریم حاوی یک دکمه و یک متن روی آن. درخت ویجت در این صفحه چطور خواهد بود؟ احتمالا چیزی شبیه به تصویر زیر:
پس یک Container داریم که ریشهی زیردرخت است و دکمه زیر مجموعهی آن است. دکمه نیز یک فرزند برای نمایش متن روی آن دارد و متن یک استایل دارد که احتمالا رنگ و فونت آن را سفارشی میکند. این ساختار درختی آنقدر ادامه پیدا میکند تا به گره برگ برسد که فرزندی ندارد.
چرخهی حیات ویجت: بطور کلی وقتی در مورد چرخهی حیات ویجت صحبت میکنیم از یک فرایند تکرارشونده به صورت زیر صحبت میکنیم:
1- ایجاد ویجت
2- بروزرسانی واسط کاربری ویجت برای بروزرسانی محتوای نمایش داده شده توسط ویجت
این فرایند بارها توسط فلاتر تکرار میشود و ما هر بار نوتیفیکیشنهایی (از طریق فراخوانی متدهای callback) دریافت میکنیم که به ما اجازه میدهد رفتار ویجتها را بروزرسانی کنیم.
انواع ویجت ها: در یک دسته بندی کلی، ویجتها در فلاتر میتوانند Stateless یا Stateful باشند:
ویجت های Stateless تصنعی (dummy) هستند یعنی مقادیر ایستا، مثل متن و آیکن نمایش می دهند. UI آنها پس از ایجاد دیگر تغییر نخواهد داشت. مولفههای Stateless توسط سیستم مدیریت میشوند و در هنگام نیاز ایجاد شده و از بین میروند (dispose).
در مقابل ویجت های Stateful هوشمند (smart) هستند و محتوای پویا نمایش میدهند (مقادیر آنها در طول حیات شان ممکن است تغییر کند). مولفههای Stateful روی چرخهی حیاتشان کنترل بیشتری دارند: هنوز هم توسط سیستم مدیریت میشوند با این تفاوت که (وقتی محتوا تغییر کرده باشد) میتوانند بروزرسانی ظاهر خود را درخواست کنند.
اشیاء State: ویجتهای Stateful یک شی state دارند که مسئول ذخیره سازی دادهای است که ویجت آن را نمایش میدهد.
ساخت ویجت: ویجتها حین اجرای متد ()build ساخته میشوند. این متد یک مولفهی بصری میسازد که به درخت ویجت اضافه خواهد شد:
Widget build(BuildContext context) { return Container( color: Colors.red, child: ... ); }
همانطور که میبینید تنها ورودی متد یک نمونه از کلاس BuildContext است. چرا برای ایجاد یک عنصر جدید به context احتیاج داریم؟
از آنجا که ویجتها در درخت ویجت پراکنده شده اند، فلاتر نیاز به روشی دارد که به عنصر مشخصی اشاره کند. برای این منظور از نمونههای کلاس BuildContext استفاده میکند. یک build context در واقع ارجاعی به موقعیت مشخص یک ویجت در درخت است.
به دلیل اهمیت درک چرخهی حیات انواع ویجت ها در فلاتر، به این مبحث به صورت کاملتر در مقالهی دیگری پرداختهام:
جمعبندی: مفاهیمی که در این مقاله توضیح داده شد را میتوان بصورت زیر خلاصه کرد: