ویجت Layout در فلاتر – Flutter
ازآنجا که مفهوم اصلی Flutter ، همه چیز ویجت است یا Everything is widget ، فلاتر لایه بدی رابط کاربری (user interface) را در ویجت های در خود گنجانده است. فلاتر بصوت کامل ابزارهای ویژه طراحی شده مانند Container, Center, Align, و غیره را برای هدف قرار دادن رابط کاربری فراهم می کند. ویجت های ساخته شده با ترکیب سایر ویجت ها معمولاً از layout widget استفاده می کنند.
در این فصل با مفهوم طراحی flutter بیشتر آشنا خواهیم شد.
مقالات
نوع Layout Widget
یجت های طرح بندی را می توان بر اساس فرزند خود به دو دسته مجزا طبقه بندی کرد –
- Widget supporting a single child – ویجت پشتیبانی از تک فرزند
- Widget supporting multiple child – ویجت پشتیبانی از چند فرزند
در بخش های بعدی هم نوع ابزارک ها و هم عملکرد آن را بیاموزیم.
ویجت Single Child فلاتر
در این گروه ، ویجت ها فقط به عنوان فرزند خود دارای یک ویجت هستند و هر ویجت از قابلیت طرح بندی layout ویژه ای برخوردار است.
به عنوان مثال ، ویجت Center فقط ویجت فرزند را با توجه به ویجت والدین خود در مرکز قرار می دهد و ویجت Container انعطاف پذیری کاملی را برای قرار دادن فرزند در هر مکان معین در داخل آن با استفاده از گزینه های مختلف مانند padding, decoration و.. فراهم می کند.
ویجت های Single child گزینه ای عالی برای ایجاد ویجت با کیفیت بالا و دارای قابلیت های واحد مانند button, label و.. است.
کد ایجاد یک button ساده با استفاده از ویجت Container بصورت زیر است –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
class MyButton extends StatelessWidget { MyButton({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Container( decoration: const BoxDecoration( border: Border( top: BorderSide(width: 1.0, color: Color(0xFFFFFFFFFF)), left: BorderSide(width: 1.0, color: Color(0xFFFFFFFFFF)), right: BorderSide(width: 1.0, color: Color(0xFFFF000000)), bottom: BorderSide(width: 1.0, color: Color(0xFFFF000000)), ), ), child: Container( padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0), decoration: const BoxDecoration( border: Border( top: BorderSide(width: 1.0, color: Color(0xFFFFDFDFDF)), left: BorderSide(width: 1.0, color: Color(0xFFFFDFDFDF)), right: BorderSide(width: 1.0, color: Color(0xFFFF7F7F7F)), bottom: BorderSide(width: 1.0, color: Color(0xFFFF7F7F7F)), ), color: Colors.grey, ), child: const Text( 'OK',textAlign: TextAlign.center, style: TextStyle(color: Colors.black) ), ), ); } } |
در اینجا ، ما از دو ابزارک استفاده کرده ایم – یک ویجت Container و یک ویجت Text . نتیجه ویجت همانطور که در شکل زیر نشان داده شده است –

ویجت Padding : با استفاده از padding دریافتی ویجت فرزند خود را مرتب می کند. در اینجا padding با کلاس EdgeInsets ایجاد می شه.
ویجت Align : ویجت فرزند خود را با استفاده از ارزش خاصیت تراز وسط خود تنظیم می کند . مقدار برای ویژگی Align کردن می تواند توسط کلاس FractionalOffset ارائه شود . کلاس FractionalOffset از نظر فاصله از بالا سمت چپ مشخص می کند.
برخی از مقادیر احتمالی offset به شرح زیر است –
- FractionalOffset (1.0 ، 0.0) نمایانگر بالا سمت راست است.
- FractionalOffset (0.0 ، 1.0) نمایانگر پایین سمت چپ است.
یک کد نمونه در مورد offset ها در زیر نشان داده شده –
1 2 3 4 5 6 7 8 9 10 11 12 |
Center( child: Container( height: 100.0, width: 100.0, color: Colors.yellow, child: Align( alignment: FractionalOffset(0.2, 0.6), child: Container( height: 40.0, width: 40.0, color: Colors.red, ), ), ), ) |
- FittedBox: ویجت فرزند را میزان ) Scale ) می کند. سپس آن را مطابق متناسب با آن تنظیم می کند.
- AspectRatio : با این ویژگی ویجت فرزند به نسبت ابعاد مشخص شده اندازه میدهد
- ConstrainedBox
- Baseline
- FractinallySizedBox
- IntrinsicHeight
- IntrinsicWidth
- LiimitedBox
- OffStage
- OverflowBox
- SizedBox
- SizedOverflowBox
- Transform
- CustomSingleChildLayout
برنامه HelloWorld ما با استفاده از متریال مبتنی بر layout widget برای طراحی صفحه اصلی می باشد. اجازه بدید برنامه HelloWorld خود را برای ایجاد صفحه اصلی با استفاده از ویجت های پایه Layout همانطور که در زیر مشخص شده است اصلاح کنیم –
- Container: Generic, single child, box based container widget with alignment, padding, border و margin
- Center – ویجت Single child container ویجت فرزند خود را مرکز قرار می دهد.
کد اصلاح شده ویجت MyHomePage و MyApp به شرح زیر است –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MyHomePage(title: "Hello World demo app"); } } class MyHomePage extends StatelessWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration(color: Colors.white,), padding: EdgeInsets.all(25), child: Center( child:Text( 'Hello World', style: TextStyle( color: Colors.black, letterSpacing: 0.5, fontSize: 20, ), textDirection: TextDirection.ltr, ), ) ); } } |
در اینجا:
- ویجت Container بالاترین سطح قرار دارد یا می توان به آن گفت ویجت ریشه. Container با استفاده از decoration و خاصیت padding برای چیدمان محتوای خود پیکربندی شده است.
- BoxDecoration از خواص بسیاری مانند color, border, و غیره برای تزئین ویجت Container استفاده می کند و در اینجا از Color برای تنظیم رنگ Container استفاده می شود.
- padding از ابزارک Container با استفاده از کلاس dgeInsets تنظیم شده است ، که این امکان را برای تعیین مقدار padding فراهم می کند.
- Center ویجت فرزند ویجت Container است . دوباره ، Text فرزند ویجت Center است . Text برای نمایش پیام استفاده می شود و از Center برای ارسال پیام متنی با توجه به ویجت والدین ، Container استفاده می شود .
نتیجه نهایی کد ذکر شده در بالا نمونه طرح مانند تصویر زیر است –

ویجت های Multiple Child
در این گروه ، یک ویجت داده شده بیش از یک ویجت child widget دارد و layout هر ویجت منحصر به فرد است.
به عنوان مثال ، ویجت Row اجازه می دهد تا فرزندان خود را در جهت افقی بگذرانید ، در حالی که ویجت Column اجازه می دهد تا فرزندان خود را در جهت عمودی بکشید. با Row و Column می توان ویجت با هر سطح پیچیدگی ایجاد کرد.
برخی از ابزارکهای مورد استفاده در این بخش:
- Row – اجازه می دهد تا فرزندان خود را به روشی افقی ترتیب دهد.
- Column – اجازه می دهد تا فرزندان خود را به صورت عمودی ترتیب دهد.
- ListView – اجازه می دهد تا فرزندان خود را به عنوان لیست ترتیب دهد.
- GridView – اجازه می دهد تا فرزندان خود را به عنوان گالری ترتیب دهند.
- Expanded – برای ساختن ویجت فرزندان Row و Column استفاده می شود تا حداکثر منطقه ممکن را اشغال کنند.
- Table – ویجت مبتنی بر جدول.
- Follow – ویجت مبتنی بر جریان.
- Stack – ویجت مبتنی بر پشته.
چیدمان پیشرفته برنامه Advanced Layout
در این بخش ، می آموزیم که چگونه یک واسط کاربری پیچیده در لیست محصولات با طراحی سفارشی با استفاده از هر دو ویجت یعنی single Child widget و multiple widget ایجاد کنید.
برای این منظور ، دنباله ذکر شده در زیر را دنبال کنید –
- یک برنامه جدید Flutter را در studio Android ، product_layout_app ایجاد کنید .
- کد main.dart با کد زیر جابجا کنید-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue,), home: MyHomePage(title: 'Product layout demo home page'), ); } } class MyHomePage extends StatelessWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(this.title),), body: Center(child: Text( 'Hello World', )), ); } } |
توضیحات کد:
در اینجا با توسعه StatelessWidget بجای StatefulWidget پیشفرض ویجت MyHomePage ایجاد کردیم و سپس کد مربوطه را حذف کردیم.
اکنون یک ویجت جدید ، ProductBox را طبق طرح مشخص شده در زیر ایجاد کنید –

کد مربوط به ProductBox به این صورته:
کد
لطفا موارد زیر را در کد رعایت کنید –
- ProductBox از چهار آرگومان
طبق آنچه در زیر مشخص شده استفاده کرده –
- name – نام محصول
- Description
– توضیحات
محصول
- Price – قیمت محصول
- Image – تصویر محصول
- ProductBox از هفت ویجت داخلی مانند آنچه در زیر مشخص شده است استفاده می کنه –
- Container
- Expanded
- Row
- Column
- Card
- Text
- Image
ProductBox با استفاده از ویجت فوق الذکر طراحی شده. ترتیب یا سلسله مراتب ویجت در نمودار نشان داده شده در زیر مشخص شده –

اکنون ، یک تصویر ساختگی (برای دیدن اطلاعات در مورد محصول) در پوشه assets برنامه قرار دهید و پوشه assets را در پرونده pubspec.yaml مانند شکل زیر تنظیم کنید –
1 2 3 4 5 6 7 |
assets: - assets/appimages/floppy.png - assets/appimages/iphone.png - assets/appimages/laptop.png - assets/appimages/pendrive.png - assets/appimages/pixel.png - assets/appimages/tablet.png |
در انتها ، از ویجت ProductBox در ویجت MyHomePage مطابق شکل زیر استفاده کنید –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
class MyHomePage extends StatelessWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title:Text("Product Listing")), body: ListView( shrinkWrap: true, padding: const EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0), children: <Widget> [ ProductBox( name: "iPhone", description: "iPhone is the stylist phone ever", price: 1000, image: "iphone.png" ), ProductBox( name: "Pixel", description: "Pixel is the most featureful phone ever", price: 800, image: "pixel.png" ), ProductBox( name: "Laptop", description: "Laptop is most productive development tool", price: 2000, image: "laptop.png" ), ProductBox( name: "Tablet", description: "Tablet is the most useful device ever for meeting", price: 1500, image: "tablet.png" ), ProductBox( name: "Pendrive", description: "Pendrive is useful storage medium", price: 100, image: "pendrive.png" ), ProductBox( name: "Floppy Drive", description: "Floppy drive is useful rescue storage medium", price: 20, image: "floppy.png" ), ], ) ); } } |
- در اینجا ، ما از ProductBox به عنوان فرزندام ویجت ListView استفاده کرده ایم .
- کد کامل (main.dart) برنامه طرح محصول (product_layout_app) به اینصورته: –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Product layout demo home page'), ); } } class MyHomePage extends StatelessWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("Product Listing")), body: ListView( shrinkWrap: true, padding: const EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0), children: <Widget>[ ProductBox( name: "iPhone", description: "iPhone is the stylist phone ever", price: 1000, image: "iphone.png" ), ProductBox( name: "Pixel", description: "Pixel is the most featureful phone ever", price: 800, image: "pixel.png" ), ProductBox( name: "Laptop", description: "Laptop is most productive development tool", price: 2000, image: "laptop.png" ), ProductBox( name: "Tablet", description: "Tablet is the most useful device ever for meeting", price: 1500, image: "tablet.png" ), ProductBox( name: "Pendrive", description: "Pendrive is useful storage medium", price: 100, image: "pendrive.png" ), ProductBox( name: "Floppy Drive", description: "Floppy drive is useful rescue storage medium", price: 20, image: "floppy.png" ), ], ) ); } } class ProductBox extends StatelessWidget { ProductBox({Key key, this.name, this.description, this.price, this.image}) : super(key: key); final String name; final String description; final int price; final String image; Widget build(BuildContext context) { return Container( padding: EdgeInsets.all(2), height: 120, child: Card( child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ Image.asset("assets/appimages/" + image), Expanded( child: Container( padding: EdgeInsets.all(5), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ Text( this.name, style: TextStyle( fontWeight: FontWeight.bold ) ), Text(this.description), Text( "Price: " + this.price.toString() ), ], ) ) ) ] ) ) ); } } |
خروجی نهایی اپلیکیشن ساخته شده:

دیدگاهتان را بنویسید