021-88881776

آموزش مفاهیم ویجت‌ها (Widgets) در Flutter

Flutter یکی از محبوب‌ترین فریم‌ورک‌های توسعه اپلیکیشن‌های موبایل است که توسط گوگل توسعه یافته است. در این آموزش Flutter، یکی از اصلی‌ترین مفاهیم آن، مفاهیم ویجت‌ها (Widgets) در Flutter می‌باشد. این مقاله آموزشی جامع و کامل، تمامی جنبه‌های این موضوع را از سطح مبتدی تا پیشرفته پوشش می‌دهد و به شما کمک می‌کند تا با استفاده از ویجت‌ها، اپلیکیشن‌های زیبا و کارآمدی بسازید.

ویجت چیست؟

در Flutter، ویجت‌ها (Widgets) عناصر ساختمانی اصلی رابط کاربری هستند که هر چیزی که روی صفحه نمایش دیده می‌شود، از آن‌ها تشکیل شده است. از متن‌ها، دکمه‌ها، تصاویر گرفته تا ساختارهای پیچیده‌تر مانند لیست‌ها و فرم‌ها، همه و همه با استفاده از ویجت‌ها ساخته می‌شوند. ویجت‌ها در Flutter به صورت سلسله‌مراتبی (Hierarchy) سازماندهی می‌شوند و می‌توانند شامل ویجت‌های داخلی دیگر باشند. این ساختار سلسله‌مراتبی به توسعه‌دهندگان امکان می‌دهد تا رابط‌های کاربری پیچیده و انعطاف‌پذیری را به شکلی ساده و قابل مدیریت ایجاد کنند.

ویژگی‌های کلیدی ویجت‌ها در Flutter

غیرقابل تغییر (Immutable): ویجت‌ها در Flutter به صورت پیش‌فرض غیرقابل تغییر هستند. به این معنا که پس از ایجاد یک ویجت، نمی‌توان ویژگی‌های آن را تغییر داد. اگر نیاز به تغییر وجود داشته باشد، باید یک ویجت جدید با ویژگی‌های جدید ایجاد شود. این ویژگی باعث می‌شود که مدیریت وضعیت (State Management) در Flutter ساده‌تر و قابل پیش‌بینی‌تر باشد.

ترکیب‌پذیری بالا: ویجت‌ها به راحتی می‌توانند با یکدیگر ترکیب شوند تا رابط‌های کاربری پیچیده‌تری بسازند. به عنوان مثال، یک ویجت Column می‌تواند شامل چندین ویجت Text، Image و Button باشد تا یک بخش از صفحه را تشکیل دهد.

سفارشی‌سازی آسان: Flutter امکان سفارشی‌سازی گسترده ویجت‌ها را فراهم می‌کند. توسعه‌دهندگان می‌توانند با استفاده از پارامترهای مختلف و ترکیب ویجت‌های پایه، ویجت‌های دلخواه خود را ایجاد کنند که دقیقا مطابق نیازهایشان باشد.

بازسازی کارآمد: هنگامی که وضعیت یک ویجت تغییر می‌کند، Flutter تنها بخش‌هایی از رابط کاربری که نیاز به تغییر دارند را بازسازی می‌کند. این فرآیند باعث افزایش کارایی و بهبود سرعت اپلیکیشن می‌شود.

ساختار سلسله‌مراتبی ویجت‌ها

یکی از قدرت‌های Flutter، ساختار سلسله‌مراتبی ویجت‌ها است. این ساختار به این صورت است که ویجت‌های ساده‌تر در بالای سلسله‌مراتب قرار دارند و ویجت‌های پیچیده‌تر از ترکیب ویجت‌های ساده‌تر ساخته می‌شوند. به عنوان مثال:

ویجت‌های پایه: مانند Text، Image و Icon که عناصر ساده‌ای از رابط کاربری را تشکیل می‌دهند.
ویجت‌های لی‌اوت: مانند Row، Column و Stack که برای چیدمان ویجت‌های دیگر استفاده می‌شوند.
ویجت‌های ترکیبی: مانند Card، ListTile و AppBar که از ترکیب ویجت‌های پایه و لی‌اوت ساخته شده‌اند.

مثال عملی

برای درک بهتر مفهوم ویجت‌ها، بیایید یک مثال عملی پیچیده‌تر را بررسی کنیم. فرض کنید می‌خواهید یک کارت اطلاعات کاربری با یک تصویر، نام، و دکمه تماس ایجاد کنید:

import 'package:flutter/material.dart';

class UserProfileCard extends StatelessWidget {
  final String imageUrl;
  final String name;

  UserProfileCard({required this.imageUrl, required this.name});

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 4.0,
      margin: EdgeInsets.all(16.0),
      child: Padding(
        padding: EdgeInsets.all(16.0),
        child: Column(
          children: [
            Image.network(imageUrl, height: 100, width: 100),
            SizedBox(height: 10),
            Text(
              name,
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {
                // عملکرد دکمه تماس
                print('تماس با $name');
              },
              child: Text('تماس'),
            ),
          ],
        ),
      ),
    );
  }
}

در این مثال:

Card: یک ویجت متریال که ظاهری برجسته و با حاشیه ایجاد می‌کند.
Padding: برای ایجاد فاصله داخلی بین محتوا و حاشیه کارت استفاده می‌شود.
Column: برای چیدمان عمودی ویجت‌های داخلی مانند تصویر، متن و دکمه.
Image.network: برای نمایش تصویر کاربر از یک URL.
Text: برای نمایش نام کاربر با استایل خاص.
ElevatedButton: برای ایجاد دکمه تماس با عملکرد مشخص.

اهمیت ویجت‌ها در توسعه اپلیکیشن‌های Flutter

ویجت‌ها اساس توسعه اپلیکیشن‌های Flutter را تشکیل می‌دهند و درک عمیق از آن‌ها برای هر توسعه‌دهنده Flutter ضروری است. با استفاده از ویجت‌ها، می‌توانید رابط‌های کاربری جذاب، پاسخگو و کارآمدی ایجاد کنید که به راحتی قابل نگهداری و توسعه هستند. علاوه بر این، آشنایی با انواع مختلف ویجت‌ها و نحوه ترکیب آن‌ها به شما کمک می‌کند تا بهترین راه‌حل‌ها را برای نیازهای خاص خود پیدا کنید.

تفاوت‌های StatelessWidget و StatefulWidget

در Flutter، دو نوع اصلی ویجت وجود دارد: StatelessWidget و StatefulWidget. تفاوت اصلی بین این دو در قابلیت تغییر وضعیت (State) آن‌هاست. در این بخش از آموزش Flutter، به بررسی دقیق‌تر تفاوت‌ها، ویژگی‌ها و کاربردهای هر کدام از این ویجت‌ها می‌پردازیم تا بتوانید تصمیم‌گیری بهتری در انتخاب مناسب‌ترین نوع ویجت برای نیازهای خود داشته باشید.

StatelessWidget چیست؟

StatelessWidget ویجت‌هایی هستند که وضعیت (State) ثابتی دارند و نمی‌توانند در طول زمان تغییر کنند. این ویجت‌ها فقط داده‌های ورودی (Properties) را نمایش می‌دهند و هیچ گونه تغییر در داده‌ها یا ظاهر آن‌ها به صورت پویا رخ نمی‌دهد. از StatelessWidget بیشتر برای نمایش اطلاعات ثابت یا ویجت‌هایی که نیازی به به‌روزرسانی مداوم ندارند، استفاده می‌شود.

ویژگی‌های کلیدی StatelessWidget

غیرقابل تغییر (Immutable): پس از ایجاد یک StatelessWidget، نمی‌توان ویژگی‌های آن را تغییر داد. اگر نیاز به تغییر وجود داشته باشد، باید یک ویجت جدید با ویژگی‌های جدید ایجاد شود.
ساده و سبک: به دلیل عدم نیاز به مدیریت وضعیت، StatelessWidget‌ها معمولاً سبک‌تر و ساده‌تر هستند.
کارایی بالا: از آنجایی که وضعیت آن‌ها ثابت است، StatelessWidget‌ها کمتر نیاز به بازسازی (Rebuild) دارند که این امر می‌تواند به بهبود کارایی اپلیکیشن کمک کند.

مثال عملی از StatelessWidget

بیایید یک مثال ساده از StatelessWidget را بررسی کنیم که یک متن ثابت را نمایش می‌دهد:

import 'package:flutter/material.dart';

class GreetingText extends StatelessWidget {
  final String message;

  GreetingText({required this.message});

  @override
  Widget build(BuildContext context) {
    return Text(
      message,
      style: TextStyle(fontSize: 24, color: Colors.blue),
    );
  }
}

در این مثال، ویجت GreetingText یک متن ثابت را نمایش می‌دهد که از طریق پارامتر message دریافت می‌شود. از آنجایی که وضعیت این ویجت تغییر نمی‌کند، از StatelessWidget استفاده شده است.

StatefulWidget چیست؟

StatefulWidget برخلاف StatelessWidget قابلیت تغییر وضعیت را دارد. این ویجت‌ها می‌توانند در طول زمان و بر اساس تعاملات کاربر یا دیگر عوامل، وضعیت خود را به‌روز کنند و به این ترتیب رابط کاربری را به صورت پویا تغییر دهند. از StatefulWidget بیشتر برای ویجت‌هایی که نیاز به به‌روزرسانی مداوم دارند، مانند فرم‌ها، لیست‌های قابل تغییر و تعاملات پیچیده‌تر، استفاده می‌شود.

ویژگی‌های کلیدی StatefulWidget

قابل تغییر (Mutable): وضعیت StatefulWidget قابل تغییر است و می‌تواند با استفاده از متد setState به‌روز شود.
مدیریت وضعیت (State Management): StatefulWidget‌ها دارای یک شیء وضعیت (State) هستند که می‌توانند وضعیت خود را مدیریت کنند.
چرخه حیات پیچیده‌تر: StatefulWidget‌ها دارای چرخه حیات پیچیده‌تری نسبت به StatelessWidget هستند که شامل متدهایی مانند initState، dispose و غیره می‌شود.

مثال عملی از StatefulWidget

در ادامه یک مثال از StatefulWidget را که یک دکمه با قابلیت تغییر رنگ در هنگام کلیک نمایش می‌دهد، مشاهده می‌کنید:

import 'package:flutter/material.dart';

class MyButton extends StatefulWidget {
  @override
  _MyButtonState createState() => _MyButtonState();
}

class _MyButtonState extends State<MyButton> {
  Color _color = Colors.blue;

  void _changeColor() {
    setState(() {
      _color = _color == Colors.blue ? Colors.red : Colors.blue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      style: ElevatedButton.styleFrom(primary: _color),
      onPressed: _changeColor,
      child: Text('کلیک کن'),
    );
  }
}

در این مثال، ویجت MyButton رنگ خود را در هر بار کلیک تغییر می‌دهد. با استفاده از setState، وضعیت ویجت به‌روزرسانی شده و رابط کاربری بازسازی می‌شود تا تغییر رنگ را نشان دهد.

مقایسه بین StatelessWidget و StatefulWidget

برای درک بهتر تفاوت‌های بین StatelessWidget و StatefulWidget، می‌توان به جنبه‌های مختلف آن‌ها به صورت زیر اشاره کرد:

تغییر وضعیت
StatelessWidget: وضعیت ویجت ثابت است و پس از ایجاد نمی‌تواند تغییر کند.
StatefulWidget: وضعیت ویجت قابل تغییر است و می‌تواند با تعاملات کاربر یا دیگر عوامل به‌روز شود.
مدیریت وضعیت
StatelessWidget: نیازی به مدیریت وضعیت ندارد و تنها داده‌های ورودی را نمایش می‌دهد.
StatefulWidget: دارای یک شیء وضعیت (State) است که وضعیت ویجت را مدیریت می‌کند و می‌تواند با استفاده از setState به‌روز شود.
پیچیدگی
StatelessWidget: ساده‌تر و سبک‌تر است زیرا نیازی به مدیریت وضعیت ندارد.
StatefulWidget: پیچیده‌تر است زیرا شامل مدیریت وضعیت و چرخه حیات ویجت می‌شود.
کاربردها
StatelessWidget: برای نمایش اطلاعات ثابت مانند متن‌ها، آیکون‌ها و تصاویر استفاده می‌شود.
StatefulWidget: برای ویجت‌هایی که نیاز به به‌روزرسانی مداوم دارند مانند دکمه‌های تعاملی، فرم‌ها و لیست‌های قابل تغییر استفاده می‌شود.

انتخاب مناسب بین StatelessWidget و StatefulWidget

انتخاب بین StatelessWidget و StatefulWidget بستگی به نیازهای خاص اپلیکیشن شما دارد:

استفاده از StatelessWidget: زمانی که ویجت شما نیازی به تغییر وضعیت ندارد و فقط باید داده‌های ورودی را نمایش دهد. این انتخاب ساده‌تر بودن کد و بهبود کارایی را به همراه دارد.

مثال: نمایش یک عنوان ثابت یا یک آیکون ساده.

class TitleText extends StatelessWidget {
  final String title;

  TitleText({required this.title});

  @override
  Widget build(BuildContext context) {
    return Text(
      title,
      style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
    );
  }
}

استفاده از StatefulWidget: زمانی که ویجت شما نیاز به تغییر وضعیت دارد، مانند پاسخ به تعاملات کاربر، تغییر داده‌ها یا به‌روزرسانی مداوم رابط کاربری.

مثال: یک فرم که نیاز به اعتبارسنجی داده‌ها دارد یا یک لیست که آیتم‌های آن می‌توانند اضافه یا حذف شوند.

class ToggleSwitch extends StatefulWidget {
  @override
  _ToggleSwitchState createState() => _ToggleSwitchState();
}

class _ToggleSwitchState extends State<ToggleSwitch> {
  bool _isOn = false;

  void _toggleSwitch() {
    setState(() {
      _isOn = !_isOn;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Switch(
      value: _isOn,
      onChanged: (value) {
        _toggleSwitch();
      },
    );
  }
}

نکات کلیدی در استفاده از StatefulWidget

به حداقل رساندن بازسازی‌ها: فقط بخش‌هایی از ویجت که نیاز به به‌روزرسانی دارند را بازسازی کنید تا کارایی بهتری داشته باشید.
تفکیک منطق و UI: سعی کنید منطق مدیریت وضعیت را از رابط کاربری جدا کنید تا کد شما خواناتر و قابل نگهداری‌تر باشد.
استفاده از ابزارهای مدیریت وضعیت: در پروژه‌های بزرگ‌تر، از ابزارهای مدیریت وضعیت مانند Provider، Bloc یا Riverpod استفاده کنید تا مدیریت وضعیت پیچیده‌تر را ساده‌تر کنید.
در این بخش از آموزش Flutter، به بررسی تفاوت‌های اصلی بین StatelessWidget و StatefulWidget پرداختیم. درک این تفاوت‌ها به شما کمک می‌کند تا ویجت مناسب را برای نیازهای خود انتخاب کنید و رابط کاربری کارآمدتری ایجاد نمایید. به خاطر داشته باشید که انتخاب درست نوع ویجت تاثیر مستقیمی بر کارایی و قابلیت نگهداری اپلیکیشن شما دارد. با استفاده از StatelessWidget برای ویجت‌های ساده و بدون نیاز به تغییر وضعیت و StatefulWidget برای ویجت‌های تعاملی و پویا، می‌توانید اپلیکیشن‌هایی با عملکرد بالا و قابل توسعه ایجاد کنید.

چرخه حیات StatefulWidget

در Flutter، StatefulWidget‌ها دارای چرخه حیات پیچیده‌تری نسبت به StatelessWidget‌ها هستند. چرخه حیات StatefulWidget شامل چندین مرحله است که در هر مرحله می‌توان عملیات خاصی انجام داد. در این بخش از آموزش Flutter، به بررسی دقیق‌تر این مراحل و نحوه عملکرد آن‌ها می‌پردازیم تا بتوانید بهینه‌ترین استفاده را از StatefulWidget‌ها داشته باشید.

مراحل اصلی چرخه حیات StatefulWidget

1. createState

این متد اولین متدی است که هنگام ایجاد یک StatefulWidget فراخوانی می‌شود. وظیفه آن ایجاد و بازگرداندن شیء وضعیت (State) مرتبط با ویجت است.

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

2. initState

متد initState یک‌بار در ابتدای ایجاد شیء وضعیت فراخوانی می‌شود. این متد برای انجام تنظیمات اولیه و راه‌اندازی داده‌ها بسیار مناسب است. در این متد می‌توانید به منابع خارجی متصل شوید، داده‌ها را بارگذاری کنید یا تنظیمات اولیه را انجام دهید.

@override
void initState() {
  super.initState();
  // تنظیمات اولیه
}

 

3. didChangeDependencies

این متد پس از initState و هر بار که وابستگی‌های ویجت تغییر کند، فراخوانی می‌شود. این متد برای واکنش به تغییرات در وابستگی‌ها مانند InheritedWidget‌ها استفاده می‌شود.

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  // واکنش به تغییرات وابستگی‌ها
}

4. build

متد build هر بار که وضعیت ویجت تغییر کند، فراخوانی می‌شود تا رابط کاربری به‌روز شود. این متد باید سریع و بهینه باشد زیرا ممکن است بارها در طول عمر ویجت فراخوانی شود.

@override
Widget build(BuildContext context) {
  return Container(
    child: Text('سلام دنیا'),
  );
}

5. setState

متد setState برای به‌روزرسانی وضعیت ویجت و بازسازی رابط کاربری استفاده می‌شود. زمانی که وضعیت ویجت تغییر کند، باید setState را فراخوانی کنید تا Flutter متوجه تغییرات شود و build را مجدداً اجرا کند.

void _updateState() {
  setState(() {
    // تغییر وضعیت
  });
}

6. dispose

متد dispose قبل از حذف ویجت از درخت ویجت‌ها فراخوانی می‌شود و برای پاکسازی منابع مورد استفاده قرار می‌گیرد. در این متد باید منابعی مانند تایمرها، کنترلرها و غیره را آزاد کنید تا از نشت حافظه جلوگیری شود.

@override
void dispose() {
  // پاکسازی منابع
  super.dispose();
}

مثال عملی: یک تایمر ساده که هر ثانیه شمارش را افزایش می‌دهد

برای درک بهتر چرخه حیات StatefulWidget، بیایید یک مثال عملی را بررسی کنیم که یک تایمر ساده را پیاده‌سازی می‌کند و هر ثانیه شمارش را افزایش می‌دهد.

import 'dart:async';
import 'package:flutter/material.dart';

class TimerWidget extends StatefulWidget {
  @override
  _TimerWidgetState createState() => _TimerWidgetState();
}

class _TimerWidgetState extends State<TimerWidget> {
  int _counter = 0;
  Timer? _timer;

  @override
  void initState() {
    super.initState();
    // راه‌اندازی تایمر
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        _counter++;
      });
    });
  }

  @override
  void dispose() {
    // لغو تایمر قبل از حذف ویجت
    _timer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Text(
      'شمارش: $_counter',
      style: TextStyle(fontSize: 24),
    );
  }
}

در این مثال:

initState: تایمر را تنظیم می‌کند تا هر ثانیه شمارش را افزایش دهد.
setState: وضعیت شمارش را به‌روز کرده و متد build را فراخوانی می‌کند تا رابط کاربری بازسازی شود.
dispose: تایمر را لغو می‌کند تا از نشت حافظه جلوگیری شود.

نکات کلیدی در مدیریت چرخه حیات StatefulWidget

شروع با initState: از initState برای راه‌اندازی داده‌ها و منابع اولیه استفاده کنید. همیشه مطمئن شوید که super.initState() را فراخوانی کنید تا اطمینان حاصل شود که چرخه حیات به درستی ادامه می‌یابد.

استفاده بهینه از setState: فقط زمانی از setState استفاده کنید که واقعاً نیاز به به‌روزرسانی وضعیت دارید. بیش از حد استفاده از setState می‌تواند به کاهش کارایی اپلیکیشن منجر شود.

پاکسازی منابع در dispose: هر منابعی که در ویجت ایجاد کرده‌اید را در dispose آزاد کنید. این شامل تایمرها، کنترلرها، و هر نوع اتصال خارجی دیگر است.

درک didChangeDependencies: اگر از InheritedWidget‌ها یا وابستگی‌های دیگر استفاده می‌کنید، از didChangeDependencies برای واکنش به تغییرات این وابستگی‌ها استفاده کنید.

اهمیت چرخه حیات StatefulWidget در توسعه اپلیکیشن‌های Flutter

درک چرخه حیات StatefulWidget برای توسعه‌دهندگان Flutter بسیار حائز اهمیت است زیرا:

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

ویجت‌های پایه (Basic Widgets)

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

Text

ویجت Text یکی از ساده‌ترین و پرکاربردترین ویجت‌های Flutter است که برای نمایش متن استفاده می‌شود. این ویجت به شما امکان می‌دهد تا متن‌های ساده یا با فرمت‌های پیچیده را به راحتی در اپلیکیشن خود نمایش دهید.

ویژگی‌های کلیدی ویجت Text

محتوا: محتوای اصلی این ویجت، متن است که می‌تواند از نوع ثابت یا متغیر باشد.
استایل: شما می‌توانید فونت، اندازه، رنگ و دیگر ویژگی‌های ظاهری متن را با استفاده از خصوصیات style تنظیم کنید.
تنظیمات ترازبندی: ویجت Text قابلیت ترازبندی متن را در داخل ویجت فراهم می‌کند.
خط شکستن و چینش: می‌توانید نحوه شکستن خطوط و چینش متن را تنظیم کنید.

مثال عملی از ویجت Text

فرض کنید می‌خواهید یک متن ساده را نمایش دهید. در Flutter، از ویجت Text برای این منظور استفاده می‌کنید:

Text('این یک متن ساده است')

همچنین می‌توانید متن را با استایل‌های مختلف سفارشی‌سازی کنید:

Text(
  'سلام Flutter!',
  style: TextStyle(
    fontSize: 24,
    fontWeight: FontWeight.bold,
    color: Colors.blue,
  ),
)

Image

ویجت Image برای نمایش تصاویر در اپلیکیشن Flutter استفاده می‌شود. این ویجت از منابع مختلفی مانند تصاویر محلی، تصاویر از اینترنت و تصاویر حافظه پنهان پشتیبانی می‌کند.

ویژگی‌های کلیدی ویجت Image

منابع تصویر: می‌توانید تصاویر را از منابع مختلف مانند network (وب)، asset (محلی) و file (فایل سیستم) بارگذاری کنید.
تنظیمات اندازه و مقیاس: امکان تنظیم ارتفاع، عرض و نحوه مقیاس‌بندی تصویر وجود دارد.
پوشش: با استفاده از خصوصیات fit می‌توانید نحوه پوشش تصویر در فضای اختصاص یافته را تنظیم کنید.
بارگذاری تصویر به صورت آسنکرون: تصاویر از منابع اینترنتی به صورت آسنکرون بارگذاری می‌شوند و می‌توانید از مکانیزم‌های بارگذاری در حال پیشرفت استفاده کنید.

مثال عملی از ویجت Image

برای نمایش یک تصویر از اینترنت، می‌توانید از ویجت Image.network استفاده کنید:

Image.network('https://example.com/image.png')

همچنین می‌توانید یک تصویر محلی را بارگذاری کنید:

Image.asset('assets/images/local_image.png')

Icon

ویجت Icon برای نمایش آیکون‌ها در اپلیکیشن Flutter استفاده می‌شود. این ویجت از مجموعه گسترده‌ای از آیکون‌های متریال و سایر مجموعه‌های آیکون پشتیبانی می‌کند.

ویژگی‌های کلیدی ویجت Icon

نوع آیکون: می‌توانید از انواع مختلف آیکون‌ها مانند آیکون‌های متریال، Cupertino و آیکون‌های سفارشی استفاده کنید.
اندازه و رنگ: امکان تنظیم اندازه و رنگ آیکون با استفاده از خصوصیات size و color وجود دارد.
پیکربندی ساده: استفاده از ویجت Icon بسیار ساده است و می‌توانید آن را به راحتی در هر جای رابط کاربری قرار دهید.

مثال عملی از ویجت Icon

برای نمایش یک آیکون قلبی با رنگ قرمز:

Icon(Icons.favorite, color: Colors.red)

ElevatedButton

ویجت ElevatedButton برای ایجاد دکمه‌های برجسته استفاده می‌شود. این ویجت یکی از ویجت‌های متریال Flutter است که با کلیک کاربر به عملکرد خاصی پاسخ می‌دهد.

ویژگی‌های کلیدی ویجت ElevatedButton

فعال/غیرفعال بودن: دکمه می‌تواند فعال یا غیرفعال باشد و بسته به وضعیت، قابلیت کلیک را داشته یا نداشته باشد.
تنظیمات استایل: می‌توانید رنگ پس‌زمینه، رنگ متن، شکل و سایه دکمه را تنظیم کنید.
اضافه کردن آیکون یا متن: می‌توانید به دکمه یک آیکون، متن یا هر دو اضافه کنید.
مدیریت رویدادهای کلیک: با استفاده از خصوصیت onPressed می‌توانید عملکردی را تعریف کنید که در هنگام کلیک بر روی دکمه اجرا شود.

مثال عملی از ویجت ElevatedButton

یک دکمه ساده با متن “دکمه”:

ElevatedButton(
  onPressed: () {},
  child: Text('دکمه'),
)

همچنین می‌توانید استایل دکمه را تنظیم کنید:

ElevatedButton(
  style: ElevatedButton.styleFrom(
    primary: Colors.green, // رنگ پس‌زمینه
    onPrimary: Colors.white, // رنگ متن
    padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
    textStyle: TextStyle(fontSize: 18),
  ),
  onPressed: () {
    print('دکمه کلیک شد!');
  },
  child: Text('دکمه سفارشی'),
)

GestureDetector

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

ویژگی‌های کلیدی ویجت GestureDetector

تشخیص حرکات مختلف: می‌توانید انواع حرکات مانند onTap، onDoubleTap, onLongPress و غیره را تشخیص دهید.
اضافه کردن تعاملات به ویجت‌های غیرتعامل‌پذیر: با استفاده از GestureDetector می‌توانید تعاملات را به ویجت‌های ساده مانند Container یا Text اضافه کنید.
انعطاف‌پذیری بالا: این ویجت به شما امکان می‌دهد تا به راحتی رفتارهای تعاملی پیچیده را پیاده‌سازی کنید.

مثال عملی از ویجت GestureDetector

یک GestureDetector که با کلیک، پیغام “Tapped” را چاپ می‌کند:

GestureDetector(
  onTap: () {
    print('Tapped');
  },
  child: Container(
    color: Colors.blue,
    width: 100,
    height: 100,
  ),
)

همچنین می‌توانید حرکات پیچیده‌تری را تشخیص دهید:

GestureDetector(
  onDoubleTap: () {
    print('Double Tapped');
  },
  onLongPress: () {
    print('Long Pressed');
  },
  child: Container(
    color: Colors.green,
    width: 150,
    height: 150,
    child: Center(child: Text('Gesture Detector')),
  ),
)

در این بخش از آموزش Flutter، با برخی از ویجت‌های پایه‌ای که برای ساخت رابط کاربری استفاده می‌شوند آشنا شدید. ویجت‌هایی مانند Text, Image, Icon, ElevatedButton و GestureDetector از جمله ابزارهای مهمی هستند که هر توسعه‌دهنده Flutter باید به خوبی با آن‌ها آشنا باشد. این ویجت‌ها پایه‌ای هستند و با ترکیب آن‌ها می‌توانید رابط‌های کاربری پیچیده و جذابی بسازید. در ادامه مقاله، به ویجت‌های لی‌اوت و سایر ویجت‌های پیشرفته‌تر خواهیم پرداخت تا دانش شما در مفاهیم ویجت‌ها (Widgets) در Flutter تکمیل شود.

Container، Row، Column، Stack، ListView و … (مبانی لی‌اوت)

در Flutter، لی‌اوت (Layout) نقش بسیار مهمی در طراحی رابط کاربری دارد. برای چیدمان و سازماندهی ویجت‌ها در صفحه، ویجت‌های مختلفی وجود دارند که هر کدام قابلیت‌ها و کاربردهای خاص خود را دارند. در این بخش از آموزش Flutter، به بررسی برخی از مهم‌ترین ویجت‌های لی‌اوت مانند Container، Row، Column، Stack و ListView می‌پردازیم و نحوه استفاده از آن‌ها را با توضیحات کامل و مثال‌های عملی بررسی می‌کنیم.

Container

ویجت Container یکی از پرکاربردترین ویجت‌های Flutter است که به عنوان یک جعبه قابل تنظیم عمل می‌کند. با استفاده از Container می‌توانید ویژگی‌هایی مانند رنگ، حاشیه، پدینگ (Padding)، مارجین (Margin) و اندازه را به ویجت‌های داخلی اعمال کنید.

ویژگی‌های کلیدی ویجت Container

رنگ پس‌زمینه: با استفاده از خصوصیت color می‌توانید رنگ پس‌زمینه‌ی Container را تنظیم کنید.
حاشیه (Margin): فاصله خارجی بین Container و ویجت‌های دیگر را با استفاده از margin تنظیم می‌کنید.
پدینگ (Padding): فاصله داخلی بین محتوای Container و لبه‌های آن را با استفاده از padding تنظیم می‌کنید.
حدود (Border): می‌توانید حاشیه‌های دور Container را با استفاده از decoration و BoxDecoration تنظیم کنید.
شکل و سایز: امکان تنظیم عرض، ارتفاع و شکل Container را دارید.

مثال عملی از ویجت Container

فرض کنید می‌خواهید یک جعبه با رنگ خاکستری و پدینگ ۱۶ پیکسل ایجاد کنید که یک متن درون آن نمایش داده شود:

Container(
  padding: EdgeInsets.all(16.0),
  color: Colors.grey[200],
  child: Text('داخل Container'),
)

همچنین می‌توانید از BoxDecoration برای اضافه کردن حاشیه و گردکردن گوشه‌ها استفاده کنید:

Container(
  padding: EdgeInsets.all(16.0),
  decoration: BoxDecoration(
    color: Colors.blueAccent,
    borderRadius: BorderRadius.circular(10),
    border: Border.all(color: Colors.black, width: 2),
  ),
  child: Text(
    'Container با حاشیه و گردکردن گوشه‌ها',
    style: TextStyle(color: Colors.white),
  ),
)

Row و Column

ویجت‌های Row و Column برای چیدمان ویجت‌ها به صورت افقی و عمودی استفاده می‌شوند. این ویجت‌ها به شما امکان می‌دهند تا چندین ویجت را در یک خط افقی یا یک ستون عمودی قرار دهید.

Row

ویجت Row برای چیدمان افقی ویجت‌ها به کار می‌رود. ویجت‌ها به ترتیب از چپ به راست در یک خط قرار می‌گیرند.

مثال عملی از Row

فرض کنید می‌خواهید یک آیکون و یک متن را در یک ردیف افقی قرار دهید:

Row(
  children: [
    Icon(Icons.star, color: Colors.yellow),
    SizedBox(width: 8), // فاصله بین آیکون و متن
    Text('ستاره'),
  ],
)

Column

ویجت Column برای چیدمان عمودی ویجت‌ها به کار می‌رود. ویجت‌ها به ترتیب از بالا به پایین در یک ستون قرار می‌گیرند.

مثال عملی از Column

فرض کنید می‌خواهید دو متن را در یک ستون عمودی قرار دهید:

Column(
  children: [
    Text('ستون 1'),
    SizedBox(height: 8), // فاصله بین دو متن
    Text('ستون 2'),
  ],
)

ویژگی‌های کلیدی Row و Column

mainAxisAlignment: برای تنظیم نحوه توزیع ویجت‌ها در محور اصلی (Row افقی و Column عمودی) استفاده می‌شود.
crossAxisAlignment: برای تنظیم نحوه تراز ویجت‌ها در محور متقابل استفاده می‌شود.
mainAxisSize: برای تعیین اندازه اصلی (Row و Column) می‌توان از آن استفاده کرد.

مثال تنظیمات Row

Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [
    Icon(Icons.home),
    Icon(Icons.settings),
    Icon(Icons.person),
  ],
)

Stack

ویجت Stack اجازه می‌دهد ویجت‌ها را روی هم قرار دهید. این ویجت به شما امکان می‌دهد تا چندین ویجت را در یک مکان قرار داده و با استفاده از ویجت‌های Positioned آن‌ها را در موقعیت‌های مختلف تنظیم کنید.

ویژگی‌های کلیدی ویجت Stack

قرارگیری ویجت‌ها روی هم: ویجت‌ها به ترتیب قرارگیریشان در Stack روی هم قرار می‌گیرند.
استفاده از Positioned: برای قرار دادن ویجت‌ها در موقعیت‌های مشخص نسبت به مرزهای Stack استفاده می‌شود.
پوشش‌دهی و طبقه‌بندی: امکان ایجاد لایه‌بندی پیچیده و پوشش‌دهی بین ویجت‌ها وجود دارد.

مثال عملی از ویجت Stack

فرض کنید می‌خواهید یک تصویر پس‌زمینه و متنی را روی آن قرار دهید:

Stack(
  children: [
    Image.network(
      'https://example.com/background.png',
      width: 300,
      height: 200,
      fit: BoxFit.cover,
    ),
    Positioned(
      bottom: 10,
      left: 10,
      child: Text(
        'متن روی تصویر',
        style: TextStyle(
          color: Colors.white,
          fontSize: 20,
          backgroundColor: Colors.black54,
        ),
      ),
    ),
  ],
)

ListView

ویجت ListView برای نمایش لیست‌های پیمایشی استفاده می‌شود. این ویجت به شما امکان می‌دهد تا لیست‌های بلند را با عملکرد بهینه نمایش دهید و از قابلیت پیمایش بهره‌مند شوید.

ویژگی‌های کلیدی ویجت ListView

پیمایش عمودی یا افقی: می‌توانید لیست را به صورت عمودی یا افقی پیمایش کنید.
عملکرد بهینه با استفاده از ListView.builder: برای لیست‌های بزرگ‌تر، از ListView.builder استفاده کنید تا تنها ویجت‌های قابل نمایش ساخته شوند و عملکرد بهتری داشته باشید.
پشتیبانی از انواع ویجت‌ها: می‌توانید انواع مختلف ویجت‌ها را در لیست قرار دهید، از جمله ListTile، Container، Card و غیره.

مثال عملی از ویجت ListView

نمایش یک لیست ساده از آیتم‌ها با استفاده از ListView:

ListView(
  children: [
    ListTile(title: Text('آیتم 1')),
    ListTile(title: Text('آیتم 2')),
    ListTile(title: Text('آیتم 3')),
    ListTile(title: Text('آیتم 4')),
    ListTile(title: Text('آیتم 5')),
  ],
)

همچنین می‌توانید از ListView.builder برای لیست‌های بزرگ‌تر استفاده کنید:

ListView.builder(
  itemCount: 100,
  itemBuilder: (context, index) {
    return ListTile(
      leading: Icon(Icons.person),
      title: Text('آیتم $index'),
    );
  },
)

ویژگی‌های پیشرفته ListView

لیست‌های قابل بازگشت (Reversed Lists): با تنظیم خصوصیت reverse می‌توانید لیست را به صورت معکوس نمایش دهید.
لیست‌های لیست‌نشده (Separated Lists): با استفاده از ListView.separated می‌توانید بین آیتم‌ها جداکننده اضافه کنید.
سفارش‌دهی و تغییر ترتیب آیتم‌ها: امکان تغییر ترتیب آیتم‌ها با استفاده از قابلیت‌های مختلف لیست وجود دارد.

مثال از ListView.separated

ListView.separated(
  itemCount: 10,
  separatorBuilder: (context, index) => Divider(color: Colors.grey),
  itemBuilder: (context, index) {
    return ListTile(
      leading: Icon(Icons.star),
      title: Text('آیتم $index'),
    );
  },
)

ویجت‌های دیگر لی‌اوت

علاوه بر ویجت‌های ذکر شده، Flutter ویجت‌های دیگری نیز برای مدیریت لی‌اوت ارائه می‌دهد که در ادامه به برخی از آن‌ها اشاره می‌کنیم:

Expanded و Flexible

ویجت‌های Expanded و Flexible برای کنترل نحوه تقسیم فضای موجود بین ویجت‌ها در داخل Row و Column استفاده می‌شوند.

مثال از Expanded

Row(
  children: [
    Expanded(
      flex: 2,
      child: Container(
        color: Colors.red,
        height: 50,
      ),
    ),
    Expanded(
      flex: 1,
      child: Container(
        color: Colors.blue,
        height: 50,
      ),
    ),
  ],
)

SizedBox

ویجت SizedBox برای ایجاد فاصله خالی با اندازه مشخص یا برای تنظیم اندازه یک ویجت خاص استفاده می‌شود.

مثال از SizedBox

Column(
  children: [
    Text('متن اول'),
    SizedBox(height: 20), // فاصله ۲۰ پیکسل
    Text('متن دوم'),
  ],
)

Spacer

ویجت Spacer برای ایجاد فاصله قابل تنظیم بین ویجت‌ها در Row یا Column استفاده می‌شود.

مثال از Spacer

Row(
  children: [
    Text('چپ'),
    Spacer(),
    Text('راست'),
  ],
)

در این بخش از آموزش Flutter، با برخی از ویجت‌های پایه‌ای که برای ساخت رابط کاربری استفاده می‌شوند آشنا شدید. ویجت‌هایی مانند Container، Row، Column، Stack و ListView ابزارهای مهمی هستند که هر توسعه‌دهنده Flutter باید به خوبی با آن‌ها آشنا باشد. این ویجت‌ها پایه‌ای هستند و با ترکیب آن‌ها می‌توانید رابط‌های کاربری پیچیده و جذابی بسازید که پاسخگوی نیازهای مختلف کاربران باشند. در ادامه مقاله، به مباحث پیشرفته‌تر مانند طراحی واکنش‌گرا و استفاده از ویجت‌های انعطاف‌پذیر خواهیم پرداخت تا دانش شما در مفاهیم ویجت‌ها (Widgets) در Flutter تکمیل شود.

لی‌اوت (Layout) و طراحی واکنش‌گرا (Responsive Design)

در Flutter، لی‌اوت (Layout) و طراحی واکنش‌گرا (Responsive Design) از جنبه‌های حیاتی برای ایجاد رابط‌های کاربری زیبا و کارآمد هستند. لی‌اوت به چگونگی سازماندهی و قرارگیری ویجت‌ها در صفحه اشاره دارد، در حالی که طراحی واکنش‌گرا تضمین می‌کند که رابط کاربری شما در اندازه‌ها و دستگاه‌های مختلف بهینه نمایش داده شود. در این بخش از آموزش Flutter، به بررسی مفاهیم اصلی لی‌اوت و طراحی واکنش‌گرا و ابزارهای Flutter برای پیاده‌سازی آن‌ها می‌پردازیم.

طراحی واکنش‌گرا

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

اهمیت طراحی واکنش‌گرا

بهبود تجربه کاربری: کاربران می‌توانند به راحتی از اپلیکیشن شما در هر دستگاهی استفاده کنند بدون اینکه نیاز به تغییرات دستی داشته باشند.
افزایش دسترسی‌پذیری: اپلیکیشن‌های واکنش‌گرا در انواع دستگاه‌ها به درستی نمایش داده می‌شوند، که باعث افزایش دسترسی‌پذیری برای کاربران مختلف می‌شود.
سئو و رتبه‌بندی بهتر: اپلیکیشن‌های واکنش‌گرا معمولاً در موتورهای جستجو بهتر رتبه‌بندی می‌شوند زیرا تجربه کاربری بهتری ارائه می‌دهند.

MediaQuery و LayoutBuilder

برای دستیابی به طراحی واکنش‌گرا، می‌توانید از ویجت‌های MediaQuery و LayoutBuilder استفاده کنید. هر دو ابزار قدرتمندی هستند که به شما امکان می‌دهند اندازه و ویژگی‌های دستگاه را دریافت کرده و بر اساس آن‌ها لی‌اوت خود را تنظیم کنید.

MediaQuery

ویجت MediaQuery اطلاعاتی درباره ابعاد و ویژگی‌های دستگاه ارائه می‌دهد. با استفاده از MediaQuery می‌توانید به ویژگی‌هایی مانند عرض و ارتفاع صفحه، جهت صفحه (عمودی یا افقی)، و وضعیت سیستم مانند اندازه فونت دسترسی پیدا کنید.

ویژگی‌های کلیدی MediaQuery

دریافت ابعاد صفحه: می‌توانید عرض و ارتفاع صفحه نمایش را دریافت کنید.
دریافت جهت صفحه: می‌توانید جهت فعلی صفحه (عمودی یا افقی) را تشخیص دهید.
دریافت تنظیمات سیستم: مانند اندازه فونت و زبانی که کاربر تنظیم کرده است.

مثال عملی از MediaQuery

فرض کنید می‌خواهید عرض صفحه را دریافت کرده و بر اساس آن ویجت‌های خود را تنظیم کنید:

import 'package:flutter/material.dart';

class ResponsiveWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    double height = MediaQuery.of(context).size.height;

    return Container(
      width: width * 0.8,
      height: height * 0.5,
      color: Colors.blue,
      child: Center(
        child: Text(
          'عرض صفحه: $width\nارتفاع صفحه: $height',
          style: TextStyle(color: Colors.white, fontSize: 18),
          textAlign: TextAlign.center,
        ),
      ),
    );
  }
}

در این مثال، Container بر اساس عرض و ارتفاع صفحه تنظیم شده و اطلاعات آن‌ها را نمایش می‌دهد.

LayoutBuilder

ویجت LayoutBuilder اندازه والد را دریافت می‌کند و می‌توانید بر اساس آن ویجت‌ها را تنظیم کنید. این ویجت برای ایجاد لی‌اوت‌های پویا و واکنش‌گرا بسیار مفید است، زیرا به شما اجازه می‌دهد تا بر اساس اندازه موجود در والد، تصمیم بگیرید که چه ویجت‌هایی را نمایش دهید.

ویژگی‌های کلیدی LayoutBuilder

دریافت اندازه والد: اندازه والد را دریافت کرده و بر اساس آن لی‌اوت را تنظیم کنید.
ایجاد لی‌اوت‌های پویا: بر اساس شرایط مختلف اندازه، ویجت‌های متفاوتی را نمایش دهید.
بهینه‌سازی عملکرد: فقط در صورت نیاز به بازسازی لی‌اوت، عملیات انجام می‌شود.

مثال عملی از LayoutBuilder

فرض کنید می‌خواهید در صورتی که عرض والد بیشتر از ۶۰۰ پیکسل باشد، یک لی‌اوت گسترده‌تر نمایش دهید و در غیر این صورت لی‌اوت ساده‌تری را نشان دهید:

import 'package:flutter/material.dart';

class ResponsiveLayout extends StatelessWidget {
  Widget _buildWideLayout() {
    return Row(
      children: [
        Expanded(child: Container(color: Colors.red, height: 100)),
        Expanded(child: Container(color: Colors.green, height: 100)),
      ],
    );
  }

  Widget _buildNormalLayout() {
    return Column(
      children: [
        Container(color: Colors.red, height: 100, width: double.infinity),
        Container(color: Colors.green, height: 100, width: double.infinity),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth > 600) {
          return _buildWideLayout();
        } else {
          return _buildNormalLayout();
        }
      },
    );
  }
}

در این مثال، با استفاده از LayoutBuilder اندازه والد بررسی شده و بر اساس آن لی‌اوت مناسب انتخاب می‌شود.

ویجت‌های انعطاف‌پذیر (Flexible، Expanded)

ویجت‌های Flexible و Expanded برای کنترل نحوه تقسیم فضای موجود بین ویجت‌ها در داخل Row و Column استفاده می‌شوند. این ویجت‌ها به شما امکان می‌دهند تا فضای موجود را به طور انعطاف‌پذیر بین ویجت‌ها تقسیم کنید.

Flexible

ویجت Flexible به ویجت‌های فرزند اجازه می‌دهد تا فضایی که در اختیار دارند را به طور انعطاف‌پذیر استفاده کنند. با استفاده از خصوصیت flex می‌توانید نسبت تقسیم فضای موجود را تعیین کنید.

ویژگی‌های کلیدی Flexible

تنظیم نسبت فضای اختصاص یافته: با استفاده از flex می‌توانید تعیین کنید هر ویجت چقدر از فضای موجود را دریافت کند.
انعطاف‌پذیری در اندازه: ویجت‌ها می‌توانند به طور پویا اندازه خود را بر اساس فضای موجود تغییر دهند.
سازگاری با سایر ویجت‌ها: به راحتی می‌توان با سایر ویجت‌های لی‌اوت ترکیب شود.

مثال عملی از Flexible

فرض کنید می‌خواهید دو ویجت در یک ردیف داشته باشید که یکی دو برابر فضای دیگری را اشغال کند:

Row(
  children: [
    Flexible(
      flex: 1,
      child: Container(
        color: Colors.red,
        height: 50,
      ),
    ),
    Flexible(
      flex: 2,
      child: Container(
        color: Colors.blue,
        height: 50,
      ),
    ),
  ],
)

در این مثال، ویجت قرمز یک بخش از فضای موجود را اشغال می‌کند و ویجت آبی دو بخش از آن را دریافت می‌کند.

Expanded

ویجت Expanded یک نسخه ساده‌تر از Flexible است که فضای باقی‌مانده را به ویجت فرزند اختصاص می‌دهد. برخلاف Flexible، Expanded همیشه تمام فضای موجود را اشغال می‌کند.

ویژگی‌های کلیدی Expanded

اشغال فضای باقی‌مانده: ویجت Expanded به طور خودکار فضای باقی‌مانده را اشغال می‌کند.
سادگی در استفاده: استفاده از Expanded ساده‌تر است زیرا نیازی به تعیین flex نیست مگر اینکه بخواهید نسبت خاصی را تنظیم کنید.
ترکیب با سایر ویجت‌ها: به راحتی می‌تواند با Row و Column ترکیب شود تا لی‌اوت‌های منعطف ایجاد کند.

مثال عملی از Expanded

فرض کنید می‌خواهید دو ویجت در یک ردیف داشته باشید که هر کدام فضای باقی‌مانده را به طور مساوی اشغال کنند:

Row(
  children: [
    Expanded(
      child: Container(
        color: Colors.green,
        height: 50,
      ),
    ),
    Expanded(
      child: Container(
        color: Colors.yellow,
        height: 50,
      ),
    ),
  ],
)

در این مثال، هر دو ویجت سبز و زرد به طور مساوی فضای باقی‌مانده را در ردیف اشغال می‌کنند.

در این بخش از آموزش Flutter، به بررسی مبانی لی‌اوت و طراحی واکنش‌گرا پرداختیم. با استفاده از ویجت‌های Container، Row، Column, Stack, ListView, Flexible و Expanded، می‌توانید لی‌اوت‌های پیچیده و واکنش‌گرا را به راحتی پیاده‌سازی کنید. همچنین با استفاده از ابزارهایی مانند MediaQuery و LayoutBuilder، می‌توانید رابط کاربری خود را به گونه‌ای طراحی کنید که در تمامی اندازه‌ها و دستگاه‌ها بهینه نمایش داده شود. در ادامه مقاله، به موضوعات پیشرفته‌تری مانند تنظیمات سایز و فاصله، ویجت‌های متریال و ویجت‌های Cupertino خواهیم پرداخت تا دانش شما در مفاهیم ویجت‌ها (Widgets) در Flutter کامل‌تر شود.

تنظیمات سایز و فاصله (Margin، Padding، Spacer)

در Flutter، تنظیمات سایز و فاصله بین ویجت‌ها یکی از جنبه‌های کلیدی طراحی رابط کاربری است. این تنظیمات به شما امکان می‌دهند تا فاصله‌های داخلی و خارجی بین ویجت‌ها را کنترل کرده و لی‌اوتی زیبا و منظم ایجاد کنید. در این بخش از آموزش Flutter، به بررسی سه ابزار اصلی برای تنظیم سایز و فاصله می‌پردازیم: Margin، Padding و Spacer.

Margin و Padding

Margin و Padding دو مفهوم مهم در طراحی لی‌اوت‌ها هستند که برای تنظیم فاصله‌های خارجی و داخلی ویجت‌ها استفاده می‌شوند.

Margin

Margin فاصله‌ای است که بین مرز خارجی یک ویجت و ویجت‌های دیگر یا والد آن ایجاد می‌شود. با استفاده از Margin می‌توانید فضای خارجی ویجت را تنظیم کرده و فاصله مناسبی بین ویجت‌ها ایجاد کنید.

مثال عملی از Margin

فرض کنید می‌خواهید یک Container با فاصله ۱۰ پیکسل از اطراف خود ایجاد کنید:

Container(
  margin: EdgeInsets.all(10.0),
  color: Colors.blue,
  child: Text('با فاصله'),
)

در این مثال، Container دارای Margin ۱۰ پیکسل از همه جهات است که فاصله‌ای یکنواخت از اطراف خود ایجاد می‌کند.

Padding

Padding فاصله‌ای است که بین محتوای داخلی یک ویجت و مرزهای آن ایجاد می‌شود. با استفاده از Padding می‌توانید فضای داخلی ویجت را تنظیم کرده و محتوا را از لبه‌های ویجت جدا کنید.

مثال عملی از Padding

فرض کنید می‌خواهید یک Container با پدینگ ۲۰ پیکسل داخلی ایجاد کنید:

Container(
  padding: EdgeInsets.all(20.0),
  color: Colors.blue,
  child: Text('با فاصله'),
)

در این مثال، Container دارای Padding ۲۰ پیکسل داخلی است که فاصله‌ای یکنواخت بین متن و لبه‌های Container ایجاد می‌کند.

تفاوت میان Margin و Padding

Margin فاصله خارجی بین ویجت‌ها را تنظیم می‌کند.
Padding فاصله داخلی بین محتوای ویجت و لبه‌های آن را تنظیم می‌کند.

مثال ترکیبی از Margin و Padding

Container(
  margin: EdgeInsets.all(10.0), // فاصله خارجی
  padding: EdgeInsets.all(20.0), // فاصله داخلی
  color: Colors.blue,
  child: Text('با فاصله'),
)

در این مثال، Container دارای هر دو Margin و Padding است که فاصله‌های خارجی و داخلی را به طور همزمان تنظیم می‌کند.

Spacer

ویجت Spacer برای ایجاد فاصله قابل تنظیم بین ویجت‌ها در یک Row یا Column استفاده می‌شود. این ویجت به شما امکان می‌دهد تا فضای خالی بین ویجت‌ها را به طور پویا و بر اساس نیاز تقسیم کنید.

ویژگی‌های کلیدی ویجت Spacer

ایجاد فاصله انعطاف‌پذیر: با استفاده از Spacer می‌توانید فاصله‌ای انعطاف‌پذیر بین ویجت‌ها ایجاد کنید که به طور خودکار فضای خالی موجود را پر می‌کند.
سادگی در استفاده: استفاده از Spacer بسیار ساده است و نیاز به تنظیمات پیچیده ندارد.
قابلیت تنظیم نسبت فاصله: با استفاده از خصوصیت flex می‌توانید نسبت تقسیم فضای خالی را بین چندین Spacer تنظیم کنید.

مثال عملی از Spacer

فرض کنید می‌خواهید دو متن را در یک ردیف با فاصله قابل تنظیم بین آن‌ها قرار دهید:

Row(
  children: [
    Text('چپ'),
    Spacer(),
    Text('راست'),
  ],
)

در این مثال، Spacer فضای خالی بین دو متن را پر می‌کند و آن‌ها را به سمت چپ و راست ردیف هدایت می‌کند.

تنظیم نسبت Spacer

می‌توانید با تنظیم خصوصیت flex نسبت تقسیم فضای خالی را تغییر دهید:

Row(
  children: [
    Text('چپ'),
    Spacer(flex: 1),
    Text('وسط'),
    Spacer(flex: 2),
    Text('راست'),
  ],
)

در این مثال، فضای بین “چپ” و “وسط” نسبت به فضای بین “وسط” و “راست” دو برابر است.تنظیمات سایز و فاصله با استفاده از Margin، Padding و Spacer ابزارهای قدرتمندی هستند که به شما امکان می‌دهند لی‌اوت‌های منظم و زیبا ایجاد کنید. با استفاده بهینه از این ابزارها، می‌توانید رابط کاربری خود را بهبود بخشیده و تجربه کاربری بهتری را فراهم آورید. در ادامه مقاله، به بررسی ویجت‌های متریال می‌پردازیم تا بتوانید از طراحی استاندارد گوگل در اپلیکیشن‌های خود بهره‌مند شوید.

ویجت‌های متریال (Material Widgets)

Flutter با استفاده از طراحی متریال گوگل، ویجت‌های متعددی ارائه می‌دهد که به شما کمک می‌کنند رابط کاربری زیبا، استاندارد و قابل اطمینان‌تری بسازید. ویجت‌های متریال شامل نوارهای ابریشمی، دکمه‌ها، منوها و بسیاری دیگر هستند که تمامی آن‌ها با اصول طراحی متریال سازگارند. در این بخش از آموزش Flutter، به بررسی برخی از مهم‌ترین ویجت‌های متریال می‌پردازیم: AppBar، Scaffold، BottomNavigationBar و Drawer.

AppBar

AppBar نوار بالای اپلیکیشن است که معمولاً شامل عنوان، آیکون‌ها و دکمه‌های مختلف می‌شود. این ویجت یکی از اجزای اصلی طراحی متریال است و به شما امکان می‌دهد تا اطلاعات مهمی مانند عنوان صفحه، آیکون‌های ناوبری و دکمه‌های عملکردی را در بالای صفحه نمایش دهید.

ویژگی‌های کلیدی ویجت AppBar

عنوان: نمایش عنوان صفحه یا اپلیکیشن.
آیکون‌ها: اضافه کردن آیکون‌های مختلف مانند دکمه منو، دکمه تنظیمات و غیره.
دکمه‌های عملکردی: اضافه کردن دکمه‌هایی که به عملکردهای خاصی در اپلیکیشن متصل هستند.
پیش‌زمینه و رنگ: امکان تنظیم رنگ پس‌زمینه و استایل AppBar.

مثال عملی از ویجت AppBar

AppBar(
  title: Text('عنوان اپلیکیشن'),
  actions: [
    IconButton(
      icon: Icon(Icons.search),
      onPressed: () {
        // عملکرد جستجو
        print('جستجو شد');
      },
    ),
    IconButton(
      icon: Icon(Icons.settings),
      onPressed: () {
        // عملکرد تنظیمات
        print('تنظیمات باز شد');
      },
    ),
  ],
)

در این مثال، AppBar شامل عنوان “عنوان اپلیکیشن” و دو آیکون جستجو و تنظیمات است که با کلیک بر روی آن‌ها عملکردهای خاصی اجرا می‌شود.

Scaffold

Scaffold یکی از ویجت‌های اصلی در طراحی متریال است که ساختار کلی یک صفحه در اپلیکیشن را فراهم می‌کند. این ویجت شامل ویژگی‌هایی مانند AppBar، Body، BottomNavigationBar، Drawer و سایر بخش‌های عمومی صفحه است.

ویژگی‌های کلیدی ویجت Scaffold

AppBar: نوار بالای صفحه.
Body: محتوای اصلی صفحه.
BottomNavigationBar: نوار پایین صفحه برای ناوبری بین بخش‌های مختلف اپلیکیشن.
Drawer: منوی کشویی که از سمت چپ صفحه ظاهر می‌شود.
FloatingActionButton: دکمه شناور برای عملکردهای خاص.

مثال عملی از ویجت Scaffold

Scaffold(
  appBar: AppBar(title: Text('صفحه اصلی')),
  body: Center(child: Text('سلام')),
  bottomNavigationBar: BottomNavigationBar(
    items: [
      BottomNavigationBarItem(icon: Icon(Icons.home), label: 'خانه'),
      BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'تنظیمات'),
    ],
  ),
)

در این مثال، Scaffold شامل یک AppBar با عنوان “صفحه اصلی”، محتوای مرکزی با متن “سلام” و یک BottomNavigationBar با دو آیتم “خانه” و “تنظیمات” است.

BottomNavigationBar

BottomNavigationBar نوار پایین صفحه است که برای ناوبری بین بخش‌های مختلف اپلیکیشن استفاده می‌شود. این ویجت معمولاً شامل چندین آیتم است که هر کدام نمایانگر یک بخش از اپلیکیشن هستند و با کلیک بر روی آن‌ها کاربر به بخش مورد نظر هدایت می‌شود.

ویژگی‌های کلیدی ویجت BottomNavigationBar

آیتم‌ها: هر آیتم شامل یک آیکون و یک عنوان است.
فعال/غیرفعال بودن آیتم‌ها: می‌توانید آیتم‌های فعال و غیرفعال را مدیریت کنید.
اتصال به رویدادهای ناوبری: با کلیک بر روی آیتم‌ها می‌توانید به بخش‌های مختلف اپلیکیشن هدایت شوید.
تنظیمات استایل: امکان تنظیم رنگ پس‌زمینه، رنگ فعال و غیرفعال بودن آیتم‌ها.

مثال عملی از ویجت BottomNavigationBar

BottomNavigationBar(
  currentIndex: 0, // شاخص آیتم فعال
  onTap: (int index) {
    // عملکرد ناوبری
    print('آیتم $index کلیک شد');
  },
  items: [
    BottomNavigationBarItem(
      icon: Icon(Icons.home),
      label: 'خانه',
    ),
    BottomNavigationBarItem(
      icon: Icon(Icons.settings),
      label: 'تنظیمات',
    ),
  ],
)

در این مثال، BottomNavigationBar شامل دو آیتم “خانه” و “تنظیمات” است. با کلیک بر روی هر آیتم، عملکرد مربوطه اجرا می‌شود.

Drawer

Drawer منوی کشویی است که معمولاً از سمت چپ صفحه ظاهر می‌شود و گزینه‌های مختلفی را برای ناوبری در اپلیکیشن ارائه می‌دهد. این ویجت به شما امکان می‌دهد تا منویی جامع و قابل دسترس برای دسترسی به بخش‌های مختلف اپلیکیشن ایجاد کنید.

ویژگی‌های کلیدی ویجت Drawer

ساختار لیست: Drawer معمولاً شامل یک لیست از گزینه‌ها است که هر کدام نمایانگر یک بخش از اپلیکیشن هستند.
منوی کشویی: با کشیدن انگشت از سمت چپ صفحه یا کلیک بر روی آیکون منو، Drawer ظاهر می‌شود.
سفارشی‌سازی آسان: می‌توانید Drawer را با استفاده از ویجت‌های مختلف مانند ListView، DrawerHeader و ListTile سفارشی‌سازی کنید.
افزودن آیکون‌ها و تصاویر: امکان اضافه کردن آیکون‌ها، تصاویر و سایر عناصر به منو وجود دارد.

مثال عملی از ویجت Drawer

Scaffold(
  appBar: AppBar(title: Text('صفحه با Drawer')),
  drawer: Drawer(
    child: ListView(
      padding: EdgeInsets.zero,
      children: [
        DrawerHeader(
          decoration: BoxDecoration(
            color: Colors.blue,
          ),
          child: Text(
            'هدر',
            style: TextStyle(
              color: Colors.white,
              fontSize: 24,
            ),
          ),
        ),
        ListTile(
          leading: Icon(Icons.home),
          title: Text('خانه'),
          onTap: () {
            // عملکرد خانه
            Navigator.pop(context);
          },
        ),
        ListTile(
          leading: Icon(Icons.settings),
          title: Text('تنظیمات'),
          onTap: () {
            // عملکرد تنظیمات
            Navigator.pop(context);
          },
        ),
      ],
    ),
  ),
  body: Center(child: Text('بدنه صفحه')),
)

در این مثال، Scaffold شامل یک AppBar با عنوان “صفحه با Drawer”، یک Drawer با یک هدر آبی و دو گزینه “خانه” و “تنظیمات” است. با کلیک بر روی هر گزینه، Drawer بسته می‌شود و عملکرد مربوطه اجرا می‌شود.

در این بخش از آموزش Flutter، با ابزارهای اصلی برای تنظیم سایز و فاصله ویجت‌ها آشنا شدید. همچنین با ویجت‌های متریال مانند AppBar، Scaffold، BottomNavigationBar و Drawer که بخش‌های کلیدی طراحی متریال را تشکیل می‌دهند، آشنا شدید. استفاده بهینه از این ابزارها به شما کمک می‌کند تا رابط کاربری زیبا، منظم و قابل استفاده‌تری در اپلیکیشن‌های Flutter خود ایجاد کنید.

تم‌ها (Theme) و رنگ‌ها (Colors)

در Flutter، تم‌ها (Theme) و رنگ‌ها (Colors) ابزارهای قدرتمندی هستند که به شما امکان می‌دهند ظاهر کلی اپلیکیشن خود را به راحتی مدیریت و سفارشی‌سازی کنید. با استفاده از تم‌ها، می‌توانید یک سبک واحد و هماهنگ برای تمامی ویجت‌های اپلیکیشن خود تعیین کنید، که این امر باعث می‌شود طراحی اپلیکیشن شما همگن و حرفه‌ای به نظر برسد. در این بخش از آموزش Flutter، به بررسی مفاهیم تم‌ها و رنگ‌ها، نحوه استفاده از آن‌ها و مثال‌های عملی می‌پردازیم.

مفهوم تم‌ها در Flutter

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

تعریف تم در Flutter

برای تعریف تم در Flutter، معمولاً از ویجت MaterialApp استفاده می‌شود و تم مورد نظر را از طریق خصوصیت theme به آن اختصاص می‌دهید. ThemeData کلاسی است که تمامی تنظیمات مربوط به تم را در خود جای داده است.

مثال عملی از تعریف تم

در مثال زیر، یک تم ساده با رنگ اصلی آبی و رنگ تکمیلی نارنجی تعریف شده است:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue, // رنگ اصلی
        accentColor: Colors.orange, // رنگ تکمیلی
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('صفحه اصلی'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {},
          child: Text('دکمه'),
        ),
      ),
    );
  }
}

در این مثال:

primarySwatch رنگ اصلی اپلیکیشن را تعیین می‌کند که در نوار بالا (AppBar) و سایر ویجت‌های متریال استفاده می‌شود.
accentColor رنگ تکمیلی است که می‌تواند برای عناصر برجسته‌تر مانند دکمه‌ها و آیکون‌ها استفاده شود.

سفارشی‌سازی تم‌ها

Flutter امکان سفارشی‌سازی گسترده‌ای را برای تم‌ها فراهم می‌کند. می‌توانید فونت‌ها، سایه‌ها، اندازه‌ها و بسیاری ویژگی‌های دیگر را به دلخواه تنظیم کنید.

مثال عملی از سفارشی‌سازی تم

در این مثال، فونت متن و رنگ پس‌زمینه بدنه صفحه تغییر یافته است:

MaterialApp(
  theme: ThemeData(
    primarySwatch: Colors.green,
    accentColor: Colors.purple,
    textTheme: TextTheme(
      bodyText1: TextStyle(fontSize: 18, fontFamily: 'Arial'),
      bodyText2: TextStyle(fontSize: 16, fontFamily: 'Roboto'),
    ),
    scaffoldBackgroundColor: Colors.grey[100],
  ),
  home: MyHomePage(),
)

استفاده از Theme.of(context)

برای دسترسی به ویژگی‌های تم تعریف شده در هر ویجت، می‌توانید از Theme.of(context) استفاده کنید. این روش به شما امکان می‌دهد تا در هر نقطه از اپلیکیشن، به تنظیمات تم دسترسی پیدا کنید و آن‌ها را اعمال کنید.

مثال عملی از استفاده Theme.of(context)

در این مثال، رنگ متن از رنگ تعریف شده در تم گرفته شده است:

Text(
  'سلام Flutter!',
  style: TextStyle(
    color: Theme.of(context).accentColor,
    fontSize: 20,
  ),
)

رنگ‌ها در Flutter

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

تعریف و استفاده از رنگ‌ها

می‌توانید رنگ‌ها را به صورت مستقیم از کلاس Colors استفاده کنید یا رنگ‌های سفارشی خود را تعریف کنید.

مثال عملی از استفاده رنگ‌های متریال

Container(
  color: Colors.blueAccent, // استفاده از رنگ متریال
  child: Text(
    'متن با رنگ آبی',
    style: TextStyle(color: Colors.white),
  ),
)

تعریف رنگ‌های سفارشی

اگر رنگ مورد نظر شما در مجموعه رنگ‌های پیش‌فرض Flutter موجود نیست، می‌توانید رنگ‌های سفارشی تعریف کنید:

Color myCustomColor = Color(0xFF42A5F5); // رنگ آبی سفارشی

Container(
  color: myCustomColor,
  child: Text(
    'متن با رنگ سفارشی',
    style: TextStyle(color: Colors.white),
  ),
)

استفاده از رنگ‌ها در تم‌ها

می‌توانید رنگ‌های مختلف را در تم‌ها تعریف کنید تا به صورت خودکار در تمامی ویجت‌های اپلیکیشن اعمال شوند.

مثال عملی از استفاده رنگ‌های سفارشی در تم

MaterialApp(
  theme: ThemeData(
    primaryColor: Color(0xFF42A5F5), // رنگ اصلی سفارشی
    accentColor: Color(0xFFFF7043), // رنگ تکمیلی سفارشی
    textTheme: TextTheme(
      bodyText1: TextStyle(color: Color(0xFF212121)),
      bodyText2: TextStyle(color: Color(0xFF757575)),
    ),
  ),
  home: MyHomePage(),
)

تم‌ها (Theme) و رنگ‌ها (Colors) ابزارهای حیاتی در طراحی رابط کاربری اپلیکیشن‌های Flutter هستند. با استفاده از آن‌ها، می‌توانید ظاهر کلی اپلیکیشن خود را به صورت یکپارچه و حرفه‌ای مدیریت کنید. تعریف تم‌های سفارشی، استفاده از رنگ‌های متریال و سفارشی، و دسترسی به تنظیمات تم در هر نقطه از اپلیکیشن به شما امکان می‌دهد تا اپلیکیشن‌های زیبا و هماهنگ‌تری بسازید.

ویجت‌های Cupertino (سبک iOS)

Flutter علاوه بر ویجت‌های متریال، ویجت‌هایی به سبک iOS نیز ارائه می‌دهد که با نام ویجت‌های Cupertino شناخته می‌شوند. این ویجت‌ها به شما امکان می‌دهند تا رابط کاربری اپلیکیشن‌های خود را شبیه به اپلیکیشن‌های iOS طراحی کنید، که برای ایجاد تجربه کاربری یکپارچه در هر دو پلتفرم Android و iOS بسیار مفید است. در این بخش از آموزش Flutter، به معرفی ویجت‌های Cupertino و نحوه استفاده از آن‌ها می‌پردازیم.

معرفی ویجت‌های Cupertino

ویجت‌های Cupertino مجموعه‌ای از ویجت‌ها هستند که ظاهر و رفتار مشابه ویجت‌های استاندارد iOS را دارند. این ویجت‌ها به شما کمک می‌کنند تا اپلیکیشن‌های خود را با طراحی بومی iOS ارائه دهید و تجربه کاربری بهتری برای کاربران iOS فراهم کنید.

برخی از ویجت‌های مهم Cupertino

CupertinoButton: دکمه‌ای به سبک iOS با انیمیشن‌های بومی و ظاهر شیک.
CupertinoNavigationBar: نوار ناوبری مشابه iOS که معمولاً شامل عنوان و دکمه‌های مختلف است.
CupertinoTabBar: نوار تب پایین به سبک iOS که برای ناوبری بین بخش‌های مختلف اپلیکیشن استفاده می‌شود.
CupertinoSwitch: سوئیچ روشن/خاموش به سبک iOS با انیمیشن‌های بومی.
CupertinoSlider: اسلایدر تنظیم مقادیر به سبک iOS.
CupertinoPicker: ویجت انتخابگر مشابه iOS که برای انتخاب مقادیر از لیست‌ها استفاده می‌شود.

استفاده از ویجت‌های Cupertino

برای استفاده از ویجت‌های Cupertino، باید پکیج cupertino را در پروژه خود وارد کنید. سپس می‌توانید از این ویجت‌ها به همان روشی که از ویجت‌های متریال استفاده می‌کنید، بهره ببرید.

مثال عملی از CupertinoButton

در این مثال، یک دکمه Cupertino با رنگ آبی فعال ایجاد می‌کنیم:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class CupertinoButtonExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoButton(
      color: CupertinoColors.activeBlue, // رنگ پس‌زمینه دکمه
      onPressed: () {
        // عملکرد دکمه
        print('دکمه Cupertino کلیک شد');
      },
      child: Text('دکمه Cupertino'),
    );
  }
}

در این مثال:

color: رنگ پس‌زمینه دکمه را تنظیم می‌کند.
onPressed: عملکردی را که هنگام کلیک بر روی دکمه اجرا می‌شود تعریف می‌کند.
child: محتوای داخلی دکمه را مشخص می‌کند که می‌تواند شامل متن، آیکون یا ترکیبی از آن‌ها باشد.

مثال عملی: CupertinoNavigationBar

در این مثال، یک نوار ناوبری مشابه iOS با عنوان و یک دکمه تنظیمات ایجاد می‌کنیم:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class CupertinoNavigationBarExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('عنوان صفحه'),
        trailing: CupertinoButton(
          padding: EdgeInsets.zero,
          child: Icon(CupertinoIcons.settings),
          onPressed: () {
            // عملکرد دکمه تنظیمات
            print('تنظیمات کلیک شد');
          },
        ),
      ),
      child: Center(
        child: Text('محتوای صفحه'),
      ),
    );
  }
}

در این مثال:

CupertinoNavigationBar شامل عنوان صفحه و یک دکمه تنظیمات است.
CupertinoPageScaffold ساختار کلی صفحه را فراهم می‌کند که شامل نوار ناوبری و محتوای اصلی است.

مزایای استفاده از ویجت‌های Cupertino

تجربه کاربری بومی: ویجت‌های Cupertino ظاهر و رفتار مشابه ویجت‌های استاندارد iOS را دارند که تجربه کاربری بومی را برای کاربران iOS فراهم می‌کند.
هماهنگی با طراحی متریال: می‌توانید ویجت‌های Cupertino را به راحتی با ویجت‌های متریال ترکیب کنید تا در هر دو پلتفرم Android و iOS ظاهر مناسبی داشته باشید.
انعطاف‌پذیری: ویجت‌های Cupertino به شما امکان می‌دهند تا رابط کاربری خود را به طور دقیق مطابق با استانداردهای طراحی iOS سفارشی‌سازی کنید.

نکات کلیدی در استفاده از ویجت‌های Cupertino

تطبیق با پلتفرم‌ها: هنگام استفاده از ویجت‌های Cupertino، اطمینان حاصل کنید که اپلیکیشن شما در هر دو پلتفرم Android و iOS به خوبی کار می‌کند. می‌توانید با استفاده از ویجت‌های Platform.isIOS و Platform.isAndroid برای انتخاب ویجت‌های مناسب برای هر پلتفرم اقدام کنید.
سفارشی‌سازی ویجت‌ها: ویجت‌های Cupertino را می‌توانید به دلخواه خود سفارشی‌سازی کنید تا با نیازهای طراحی شما مطابقت داشته باشند.
استفاده از CupertinoApp: اگر قصد دارید بیشتر از ویجت‌های Cupertino استفاده کنید، می‌توانید از ویجت CupertinoApp به جای MaterialApp استفاده کنید تا تنظیمات بومی iOS را به طور کامل پیاده‌سازی کنید.

مثال عملی از ترکیب ویجت‌های متریال و Cupertino

در این مثال، از هر دو نوع ویجت‌های متریال و Cupertino در یک اپلیکیشن استفاده می‌کنیم تا تجربه کاربری بهتری را ارائه دهیم:

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('صفحه اصلی'),
        actions: [
          CupertinoButton(
            padding: EdgeInsets.zero,
            child: Icon(CupertinoIcons.add),
            onPressed: () {
              print('دکمه Cupertino در AppBar کلیک شد');
            },
          ),
        ],
      ),
      body: Center(
        child: CupertinoButton(
          color: CupertinoColors.activeGreen,
          onPressed: () {
            print('دکمه Cupertino در بدنه صفحه کلیک شد');
          },
          child: Text('دکمه Cupertino'),
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'خانه'),
          BottomNavigationBarItem(icon: Icon(CupertinoIcons.settings), label: 'تنظیمات'),
        ],
      ),
    );
  }
}

در این مثال:

از ویجت‌های متریال مانند MaterialApp، Scaffold و AppBar استفاده شده است.
ویجت‌های Cupertino مانند CupertinoButton و CupertinoIcons برای ایجاد دکمه‌ها و آیکون‌های بومی iOS استفاده شده‌اند.
با ترکیب این دو نوع ویجت، می‌توان اپلیکیشنی ایجاد کرد که در هر دو پلتفرم Android و iOS ظاهر مناسبی داشته باشد. ویجت‌های Cupertino (سبک iOS) در Flutter به شما امکان می‌دهند تا رابط کاربری اپلیکیشن‌های خود را به صورت بومی و مشابه اپلیکیشن‌های iOS طراحی کنید. با استفاده از این ویجت‌ها، می‌توانید تجربه کاربری بهتری را برای کاربران iOS فراهم آورید و اپلیکیشنی هماهنگ و حرفه‌ای ارائه دهید. ترکیب ویجت‌های متریال و Cupertino نیز امکان طراحی اپلیکیشنی با ظاهر منسجم در هر دو پلتفرم Android و iOS را فراهم می‌کند.

نتیجه‌گیری

در این مقاله به بررسی جامع و کامل مفاهیم ویجت‌ها (Widgets) در Flutter پرداختیم. از معرفی ویجت‌های پایه‌ای مانند Text، Image، Icon، ElevatedButton و GestureDetector تا مباحث پیشرفته‌تر مرتبط با لی‌اوت و طراحی واکنش‌گرا با استفاده از Container، Row، Column، Stack و ListView، تمامی جنبه‌های اصلی این موضوع را پوشش دادیم. همچنین با مفاهیم مهمی مانند تنظیمات سایز و فاصله با استفاده از Margin، Padding و Spacer آشنا شدیم و نحوه مدیریت ظاهر کلی اپلیکیشن با استفاده از تم‌ها و رنگ‌ها را بررسی کردیم.

علاوه بر این، به معرفی ویجت‌های Cupertino (سبک iOS) پرداختیم که به شما امکان می‌دهند تا رابط کاربری اپلیکیشن‌های خود را به شکلی مشابه اپلیکیشن‌های iOS طراحی کنید. این ویجت‌ها به ویژه برای توسعه‌دهندگانی که قصد دارند اپلیکیشنی چندپلتفرمی با ظاهر بومی برای هر دو سیستم‌عامل Android و iOS ایجاد کنند، بسیار مفید هستند.

درک عمیق از مفاهیم ویجت‌ها (Widgets) در Flutter به شما این امکان را می‌دهد که اپلیکیشن‌هایی زیبا، کارآمد و قابل نگهداری ایجاد کنید. با استفاده از ترکیب مناسب ویجت‌ها و بهره‌گیری از ابزارهای ارائه شده توسط Flutter، می‌توانید رابط‌های کاربری پیچیده و پاسخگو را به شکلی ساده و موثر پیاده‌سازی کنید.

برای ارتقاء مهارت‌های خود در توسعه اپلیکیشن‌های Flutter، توصیه می‌شود که به مطالعه منابع معتبر همچون مستندات رسمی Flutter، کتاب‌ها و دوره‌های آموزشی آنلاین بپردازید و با تمرین مستمر، تجربیات عملی بیشتری کسب کنید. همچنین، آشنایی با ابزارهای مدیریت وضعیت مانند Provider، Bloc یا Riverpod می‌تواند به بهبود ساختار و کارایی اپلیکیشن‌های شما کمک کند.

آموزش مفاهیم ویجت‌ها (Widgets) در Flutter

دیدگاه های شما

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

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *