فلاتر یک محیط توسعه برای گوشی های هوشمند است که توسط گوگل ارئه شده. توسط فلاتر میشه هم برای اندروید و هم برای ایاواس با یک کد (تقریبا) برنامههای مدرن توسعه داد. برخلاف دیگر محیطهای توسعه کراس پلت فرم، مانند ریکت نیتیو، فلاتر از جاوا اسکریپت استفاده نمیکنه و یک زبان مخصوص به خودش رو داره به اسم دارت (Dart). طبق آمار استکاورفلو فلاتر پیش رونده ترین تکنولوژی برنامه نویسی در حال حاضر است.
این نکته رو هم بگم که من زیاد با فلاتر آشنایی ندارم و فقط چون این آموزش برام جالب بود اون رو نوشتم. منبع رو هم اینجا میتونید ببینید.
دراور تقریبا یک صفحه نمایش نامرئی ست که معمولا یک لیست یا منو در داخل خود دارد. وقتی نمایش داده میشود معمولا نصف صفحه نمایش یا بیشتر را پر میکند. چیزی شبیه به تصویر زیر:
اول یک دراور خالی درست کنیم. برای استفاده از متریال دیزاین از MaterialApp استفاده میکنیم. کد زیر:
class MyApp extends StatelessWidget { @override Widget build (BuildContext ctxt) { return new MaterialApp( home: new DWidget() ); } }
تابع DWidget رو پایین تر مینویسیم. باید به این نکته اشاره کنم که چون drawers بخشی از Scaffold و appBar هست به محظ اضافه شدن دراور به برنامه، یک آیکون سه خطی به قسمت بالا و سمت چپ برنامه اضافه میشه که با لمس اون دراور باز میشه.
کد پایین تابع DWidget هست که در بالا از اون استفاده کردیم:
class DWidget extends StatelessWidget { @override Widget build (BuildContext ctxt) { return new Scaffold( drawer: new Drawer( child: new Text("\n\n\nDrawer Is Here"), ), appBar: new AppBar( title: new Text("Drawer Demo"), ), body: new Text("Drawer Body"), ); } }
خروجی برنامه:
اگر در کد بالا دقت کنید ما به جای :children از :child استفاده کردیم. استفاده از :child یعنی ما فقط میتونیم از یک ویجت داخل دراور استفاده کنیم.
برای استفاده از ویجت های بیشتر باید از ویجتهایی استفاده کنیم که قادر به نگه داشتن چندین ویجت به صورت ستونی هستند.
کد دراور در صورت استفاده از حالت ستونی به صورت زیر خواهد بود:
drawer: new Drawer( child: new Column( children: <Widget>[ new Text("\n\n\n\Drawer Is Here => 1"), new Text("Drawer Is Here => 2"), new Text("Drawer Is Here => 3"), ], ) ),
این کد سه عدد تکست رو در دراور به ما نشون میده.
معمولا هر دراور در قسمت بالایی خود شامل یک هدر است. اندازه هدر تقریبا ۲۰٪ از کل اندازه دراور رو در بر میگیره. در فلاتر ما میتونیم از ویجت DrawerHeader استفاده کنیم که میتونه دارای زیر مجموعه هم باشه. در اینجا ما از BoxDecoration استفاده میکنیم که راحتتر بتونیم مرز کامل هدر رو تشخیص بدیم.
drawer: new Drawer( child:new DrawerHeader( child: new Text("DRAWER HEADER.."), decoration: new BoxDecoration( color: Colors.orange ), ) ),
و خروجی برنامه:
هدری که ساختیم ۱۰۰٪ از فضای دراور رو در بر گرفته. در حالی که انتظار داشتیم اندازه هدر ۲۰٪ باشه. این اتفاق وقتی رخ میده که ما فقط هدر داخل دراور داشته باشیم. در واقع دراور انتظار داره به غیر از هدر یک یا چند ویجت دیگه داخلش داشته باشه.
برای نمایش صحیح هدر باید از ویجت هایی استفاده کنیم که خودشون میتونند شامل چند ویجت دیگه باشن. برای نمونه Column یا ListView.
اینجا ما از ListView استفاده میکنیم. چون Column کل محیط رو پر نمیکنه.
طبق کد زیر ListView رو به دراور اضافه میکنیم:
drawer: new Drawer( child: new ListView( children: <Widget>[ new DrawerHeader( child: new Text("DRAWER HEADER.."), decoration: new BoxDecoration( color: Colors.orange ), ) ], ) ),
خروجی برنامه :
این چیزی بود که از اول دنبالش بودیم. حالا دراوری که درست کردیم استاندارد به نظر میاد.
معمولا دراورها شامل یک سری آیتم هستند که با لمس اونها اعمالی انجام میشه. مثلا باز کردن یک اکتیویتی یا صفحه. ما باید از ویجت هایی استفاده کنیم که از تابع onTap پشتیبانی کنند.
یکی از ویجت هایی که ما میتونیم در ListView استفاده کنیم ListTile هست.
حالا بیاید با استفاده از ListTile و تابع onTap چندتا آیتم به دراور اضافه کنیم. تابع onTap همون کار کلیکلیسنر در اندروید رو برای ما انجام میده البته با انعطاف پذیری بیشتر.
کد زیر دو صفحه به برنامه ما اضافه میکنه که کاربر با لمس هر آیتم در دراور میتونه اونهارو ببینه.
class FirstPage extends StatelessWidget { @override Widget build(BuildContext ctxt) { return new Scaffold( appBar: new AppBar(title: new Text("First Page"),), body: new Text("I belongs to First Page"), ); } }
class SecondPage extends StatelessWidget { @override Widget build(BuildContext ctxt) { return new Scaffold( appBar: new AppBar(title: new Text("Second Page"),), body: new Text("I belongs to Second Page"), ); } }
حالا با استفاده از تابع onTop در ListTile صفحاتی که درست کردیم رو به کاربر نشون میدیم.
drawer: new Drawer( child: new ListView( children: <Widget>[ new DrawerHeader( child: new Text("DRAWER HEADER.."), decoration: new BoxDecoration( color: Colors.orange ), ), new ListTile( title: new Text("Item => 1"), onTap: () { Navigator.push(ctxt, new MaterialPageRoute(builder: (ctxt) => new FirstPage())); }, ), new ListTile( title: new Text("Item => 2"), onTap: () { Navigator.push(ctxt, new MaterialPageRoute(builder: (ctxt) => new SecondPage())); }, ), ], ) ),
در اینجا با استفاده از ListTile ما دو آیتم به دراور اضافه کردیم. بعد با استفاده از تابع onTop هر کدوم از اونها رو به صفحاتی که میخوایم ربط میدیم.
خروجی برنامه رو ببینید:
تقریبا کارمون تموم شد. اما اگر دقت کنید وقتی میخوایم از صفحه ای که داخلش هستیم برگردیم به صفحه اصلی، به جای بازگشت، دراور دوباره باز میشه.
برای حل این مشکل ما باید کاری کنیم که دراور تا قبل از بارگذاری صفحه جدید، نمایش داده نشه. برای این کار از ()Navigator.pop استفاده میکنیم. متدهای ()onTop رو طبق کد زیر تغییر بدید:
onTap: () { Navigator.pop(ctxt); Navigator.push(ctxt, new MaterialPageRoute(builder: (ctxt) => new FirstPage())); },
و خروجی برنامه: