نحوه ریسپانسیو کردن Ui در فلاتر

با سلام و وقت بخیر خدمت شما عزیزان

توی این آموزش قصد داریم بررسی کنیم که چه ویجت هایی رو فلاتر برای ریسپانسیو کردن ui معرفی کرده...

و در مورد بعضی از ویجت ها هم تا حد ممکن توضیح بدیم ، هدف ما در این آموزش آشنایی اولیه با مفاهیم و ویجت ها هست و برای درک بهتر هر ویجت، صورت جداگانه ویجت رو سرچ کنید و مثال های مختلف رو ببینید.

لیست برخی از ویجت های پرکاربرد:

MediaQuery - LayoutBuilder - OrientationBuilder - SafeArea - AspectRatio - Flexible - Expanded -FractionalSizedBox and ...

اولین مفهومی که قصد داریم معرفی کنیم مدیا کوئری هست .

با استفاده از مدیا کوئری ما میتونیم به طول ، عرض و جهت صفحه نمایش دسترسی پیدا کنیم.

ما در پایین سه متغییر تعریف کردیم به نام screenHeight ,screenWidth , orientation که با استفاده از دستورات زیر ما به ترتیب عرض و طول و جهت صفحه نمایش (که صفحه نمایش ما افقی هست و یا عمودی) رو در داخل متغییر هامون قرار میدیم

double screenWidth = MediaQuery.of(context).size.width;

double screenHeight = MediaQuery.of(context).size.height;

Orientation orientation = MediaQuery.of(context).orientation;

برای اینکه در قالب مثال توضیح داده باشیم من یک اپ ساده که فقط یک متن رو در وسط صفحه نمایش میده رو با استفاده از شبیه ساز ایفون اجرا کردم،و در متد بیلد سه تا متغییر رو تعریف کردم و همونطور که در تصویر بالا مشاهده میکنید ،دستور پرینت سه تا متغییر رو قرار دادیم و وقتی برنامه رو اجرا میکنیم، به ما نشون میده که عرض آیفون ما ۳۹۰ هست و ارتفاع ۸۴۴ و جهت اون هم عمودی هست. به همین راحتی تونستیم طول و عرض جهت صفحه نمایش رو نمایش بدیم.

خوب حالا که دربالا متوجه شدیم میتونیم با استفاده از مدیا کوئری سایز صفحه رو بگیریم چه مزیتی برای ما داره ؟

یکی از مزیت هاش این هست که میتونیم در بدنه برنامه شرط بزاریم که اگه طول و عرض صفحه ما از یه اندازه ای کمتر بود شما بیا و این صفحه رو نمایش بده و اگه بیشتر بود یه صفحه دیگه رو(با ویجت هایی با طول و عرض متفاوت) نمایش بده، کجا کاربرد داره؟ وقتی ما میخوایم ui خودمون رو برای تبلت ها بهینه کنیم یا سایزهای مختلف تلفن های همراه:

خیلی ساده بخوام مثال بزنم

ما در برنامه بالا یه شرط ساده گذاشتیم و گفتیم اگه width صفحه نمایش ما کوچکتر از ۵۰۰ بود شما بیا متن ما رو با فونت سایز ۳۰ و رنگ زرد نمایش بده در غیر این صورت و بزرگتر بودن سایز بیا و متن رو با فونت سایز ۴۰ و رنگ آبی نمایش بده،این مثال خیلی ساده بود ولی شما میتونید به صورت کامل یک ویجت رو با دو سایز مختلف برای نمایش در موبایل و تبلت بهینه کنید ما اینجا از این نوع شرط گذاری استفاده کردیم

condition ? : ,

قبل از علامت سوال شرط رو میزاریم ، بعد علامت سوال کاری که باید انجام بشه،و بعد دو نقطه هم کاری که در صورت اینکه شرط اولیه ما اجرا نشه...

خیلی بهینه تر بخوایم مثال بزنیم با استفاده از متد OrientaionBuilder هم میتونیم مثل تصویر زیر شرط بزاریم که براساس سایز صفحه نمایش کدوم View ما رو نمایش بده.

خوب بریم سراغ یکی از مثال های کاربردی:

ما با استفاده از مدیا کوئری میتونیم سایز ویجت هامون رو بر اساس سایز صفحه تعیین کنیم..

برای مثال میتونیم تعیین کنیم که ارتفاع ویجت ما ۳۰ درصد ارتفاع صفحه باشه با استفاده از دستور زیر میتونیم این کارو انجام بدیم:

MediaQuery.of(context).size.height * 0.30;

نکته ( صفر اخر رو هم نزاریم بازم ۳۰ درصد رو میگیره،یا مثلا میتونیم بگیم ۰.۰۲ یعنی دو درصد کل صفحه)

و یا اینکه به این صورت هم میشه تعیین کرد که ویجت ما نصف ارتفاع صفحه باشه:

MediaQuery.of(context).size.height / 2;

مثال زیر رو مشاهده کنید.

ما در بالا دوتا container ساختیم که در اولی با استفاده از دستور double.infinity گفتیم عرضش به اندازه کل صفحه باشه و ارتفاعش هم ۳۰ درصد کل صفحه باشه...

و در container پایین هم ارتفاعی تعیین نکردیم وگفتیم خود به خود به اندازه طول ویجت های فرزندش ارتفاعش تنظیم میشه...

خوب تا جای ممکن سعی کردیم مفهوم مدیا کوئری رو توضیح بدیم چون بسیار کاربردی هست و خیلی برای رسپانسیو کردن صفحات به ما کمک میکنه....

در قسمت دوم در مورد ویجت های مهم و کاربردی Expanded & Flexible صحبت میکنیم

قبل از اینکه وارد توضیحات مربوط به ویجت Expanded بشیم،مثال زیر رو مشاهده کنید

در تصویر بالا مشاهده میکنید که سه تا container داریم که در عرض صفحه قرار گرفتند...

خوب حالا اگه که بخوایم container هارو به صورت هم اندازه طوری گسترش بدیم که کامل عرض صفحه رو بگیرن از Expanded استفاده میکنیم

ویجت Expanded همانطور که از اسمش پیداست ، ویجتی هست که گسترش میده یک Child رو در داخل Row یا Column برنامه فلاتری ما...در مثال پایین متوجه کاربرد این ویجت میشیم

در بالا دومین container رو wrap کردیم با یک ویدجت Expanded و مشخصه width رو هم حذف کردیم خود به خود تشخیص میده و خودش رو گسترش و یا بسط میده در اون ویجتی که هست و کل صفحه رو در بر میگیره.

در مثال پایین سه تا Container رو wrap میکنیم به Expanded و همونطور که نتیجه رو مشاهده میکنید

سه تا container رو به صورت برابر در عرض صفحه تقسیم میکنه،با استفاده از Expanded

ویجت Expanded یک مشخصه به اسم flex داره که وقتی ما یک مقدار به این flex میدیم به طور غیر یکنواخت ویجت های مارو در اون سطر یا ستون ما گسترس میده،مقدارش به طور پیش فرض یک هست

مثال پایین رو مشاهده کنید.

ما در اولین ویجت مقدار flex رو ۴ قرار میدیم و دومی رو برابر۲ و سومی رو هم یک قرار میدیم..که در مجموع برابر ۷ میشه،یعنی عرض صفحه ما ۷ بخش میشه و container اولی ۴ بخشش رو به خودش اختصاص میده ..

نکته ای که هست اینه که اگر عددی قرار ندیم خودش مقدار پیشفرضش رو برابر یک قرار میده

ویجت Flexible

ویجت Flexible کاملا شبیه به Expanded هست و یک تفاوت داره که در مثال های پایین به اون اشاره میکنیم،

همینطور که مثال زیر رو مشاهده میکنید یک سطر داریم که سه Container رو در اون قرار دادیم و به ترتیب مثل مثال Expanded مقدار دهی کردیم Flex های هر ویجت Flexible رو که در مجموع شدن شش قسمت و اولی سه قسمت صفحه رو پوشش داده..

اگه که ما بخوایم به یکی از Container ها ارتفاع دلخواه بدیم، طبق کد پایین که با فلش مشخص کردیم،

و اومدیم ارتفاع رو برابر ۱۵۰ قرار داریم،ویجت کاری نداره با مشخصه Flex و این مقدار رو به عنوان ارتفاع این ویجت قرار میده و کاری نداره با اینکه کل صفحه رو پوشش میده یا نه...

در Expanded ما نمیتونیم مثل بالا وقتی از flex استفاده میکنیم height رو بر اساس مقدار دلخواه خودمون مقدار دهی کنیم.

اگه بخوایم ویجت رو مجبور کنیم کل فضای خالی صفحه رو بگیره از مشخصه fit استفاده میکنیم

دوتا گزینه داره FlexFit.tight و گزینه پیشفرضی اون Flexfit.losse هست که تفاوتشون در اینه که وقتی از این مشخصه استفاده میکنیم کل صفحه رو پوشش میده و دیگه کاری با سایزی که ما میدیم به Container نداره...

ولی وقتی از Flexfit.loose استفاده میکنیم میتونیم هر کدوم از ویجت های دلخواه خودمون رو مقدار دهی کنیم.در Flexible آزادی عملی برای کنترل گسترش ویجت ها نسبت به Expanded داریم.

تفاوت Expanded و Flexible هم این متد Fit هست.

یه مثال ساده دیگه برای درک کامل تر،در مثال پایین یه container داریم و یک Flexible که درون خودش یک Container داره و ارتفاع هردو اون ها برابر با ۲۰۰ هست

حالا وقتی ما بیایم و Container دومی رو بزرگترکنیم ارتفاعش ..Flexible ارتفاع خودش رو نادیده میگیره و براساس Container سایزش تغییر میکنه.

ویجت SafeArea :

همینطور که در تصویر زیر مشاهده میکنید این ویجت برای این هست که بدنه برنامه ما زیر استاتوس و ... قرار نگیره و یک مقداری از بالا فاصله داشته باشه،خیلی راحت میتونیم بدنه رو با این ویجت wrap کنیم.

ویجت LayoutBuilder:

ویجت کاربردی هست که با استفاده از اون میتونیم به BoxConstraints هر ویجت دسترسی پیدا کنیم که ‌BoxConstraint مشخص کننده طول و عرض کامل ویجت هست و برای متوجه شدن تفاوت LayoutBuilder و MediaQuery ابتدا مثال زیر رو ببینید.

در مثال بالا ما یک ستون داریم که صفحه رو به دو قسمت تقسیم کردیم که مقدار مدیا کوئری توی هر دو قسمت برابر هست ولی مقدار LayoutBuilder فرق میکنه به این خاطر هست مدیا کوئری عرض کل صفحه رو حساب میکنه ولی در لایوت بیلدر مقدار عرض اون ویجتی که در اون هستیم رو نمایش میده، برای مثال عرض قسمت بنفش رنگ رو برابر ۱۵۶ قرار داده که جمعش با عرض قسمت سفید رنگ برابر میشه با عرض کل برنامه..

معرفی چند منبع برای یادگیری کامل تر این مطالب: 

https://docs.flutter.dev/development/ui/layout/adaptive-responsive

https://blog.codemagic.io/building-responsive-applications-with-flutter/

https://www.youtube.com/watch?v=WUZVO1CLXqw

https://medium.com/flutter-community/flutter-widgets-expanded-flexible-acc945829584

ممنون که همراه من بودین تا پایان این آموزش

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

هرجایی نکته نیاز به تصحیح داشت و یا کم گفته بودم ممنون میشم توی کامنت ها اطلاع بدین که پست رو اصلاح کنم.

موفق باشید

یاعلی