Flutter Widgets — این چیست، درخت ویجت و build

نویسنده: IT Sectr منتشر شده: 2026-02-21 زمان مطالعه: 8 دقیقه

Flutter Widgets — بلوک‌های ساختمانی پایه رابط کاربر در چارچوب Google Flutter هستند که در نسخه پایدار 1.0 در دسامبر 2018 منتشر شد. در Flutter همه چیز یک ویجت است: از صفحه و دکمه گرفته تا فاصله و ترازبندی. ویجت‌ها درختی (widget tree) تشکیل می‌دهند که Flutter آن را در موتور خود Skia/Impeller رندر می‌کند و از ماژول‌های سیستم‌عامل اسکیب می‌کند. به گزارش Google I/O (2025)، Flutter در بیش از 500 000 برنامه در Google Play و App Store استفاده می‌شود. معماری Flutter ویجت‌ها را به StatelessWidget (تغییرناپذیر) و StatefulWidget (با وضعیت تغییرپذیر از طریق شئ‌ء State) تقسیم می‌کند.

نکات کلیدی

  • Flutter Widgets — همه المان‌های UI در Flutter: از صفحه و دکمه تا فاصله و ترازبندی؛ چارچوب از ماژول‌های سیستم‌عامل استفاده نمی‌کند.
  • StatelessWidget — ویجت بدون وضعیت تغییرپذیر؛ داده‌های ارسالی از طریق سازنده را نمایش می‌دهد و پس از ساخت (build) تغییر نمی‌کند.
  • StatefulWidget — ویجت با وضعیت تغییرپذیر که در شئ‌ء جداگانه‌ء State ذخیره می‌شود و از rebuildها جان سالم به در می‌آید.
  • درخت ویجت‌ها (widget tree) — سلسله‌مراتب ویجت‌هایی که UI را توصیف می‌کنند؛ Flutter آن را برای رندر به Element Tree و Render Tree تبدیل می‌کند.
  • BuildContext — زمینه ساخت، دسترسی به موقعیت ویجت در درخت، پوسته، MediaQuery و InheritedWidget را فراهم می‌کند.

Flutter Widgets چیست؟

Flutter Widgets — همه المان‌های UI در چارچوب Flutter هستند که به عنوان کلاس‌های Dart تغییرناپذیر (immutable) پیاده‌سازی شده‌اند. ویجت پیکربندی از یک المان UI است: اندازه، رنگ، موقعیت، توابع رویدادگر. بر خلاف Android (XML + View) یا iOS (Storyboard + UIView)، Flutter از ماژول‌های سیستم‌عامل استفاده نمی‌کند — همه چیز توسط موتور Skia (Android/iOS/Linux) یا Impeller (iOS/macOS) روی Canvas رسم می‌شود. این ظاهر یکسانی را در تمام سیستم‌عامل‌ها بدون تفاوت‌های سیستم‌عاملی تضمین می‌کند. Flutter با دو مجموعه ویجت ارائه می‌شود: Material Widgets (طراحی Google Material Design 3 برای Android/Web) و Cupertino Widgets (طراحی Apple HIG برای iOS/macOS). توسعه‌دهنده می‌تواند هر دو مجموعه را در یک برنامه ترکیب کند. هر ویجت روش build() را دارد که یک ویجت فرعی یا ترکیبی از آنها را بازمی‌گرداند — درخت ویجت‌ها به این طریق ساخته می‌شود.

سه درخت Flutter

Flutter با سه درخت کار می‌کند: Widget Tree (پیکربندی، توسط توسعه‌دهنده ایجاد می‌شود)، Element Tree (ابزار مقابل ویجت با موقعیت در درخت، مدیریت توسط چارچوب)، Render Tree (شئ‌هایی که layout را محاسبه و paint را انجام می‌دهند). Widget Element را ایجاد می‌کند که RenderObject را ایجاد می‌کند. Element در زمان تغییر پیکربندی (rebuild) مجدداً استفاده می‌شود — این مکانیسم بهینه‌سازی Flutter است: اگر نوع ویجت و key یکسان باشند، Element مجدداً ایجاد نمی‌شود، بلکه پیکربندی جدید به‌روز می‌شود. درک سه درخت کلید بهینه‌سازی عملکرد برنامه‌های Flutter است.

StatelessWidget: ویجت‌های تغییرناپذیر

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

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

class ProfileHeader extends StatelessWidget {
  final String name;
  final String avatarUrl;

  const ProfileHeader({super.key, required this.name, required this.avatarUrl});

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        CircleAvatar(
          radius: 24,
          backgroundImage: NetworkImage(avatarUrl),
        ),
        const SizedBox(width: 12),
        Text(
          name,
          style: const TextStyle(
            fontSize: 18,
            fontWeight: FontWeight.bold,
          ),
        ),
      ],
    );
  }
}

ProfileHeader — StatelessWidgetی است که name و avatarUrl را از طریق سازنده می‌پذیرد. CircleAvatar آواتار و Text نام را نمایش می‌دهد. ویجت نمی‌تواند این مقادیر را پس از ایجاد تغییر دهد. استفاده از سازنده const (const ProfileHeader) به Flutter اجازه می‌دهد در زمان rebuild والد از نمونه ویجت مجدداً استفاده کند — این یک ریزبهینه‌سازی است که برای همه StatelessWidget توصیه می‌شود.

StatefulWidget: ویجت‌های با وضعیت

StatefulWidget — ویجتی با وضعیت تغییرپذیر که در شئ‌ء State جداگانه ذخیره می‌شود. خود StatefulWidget مانند StatelessWidget تغییرناپذیر (immutable) است. بخش تغییرپذیر در State جا گذاشته شده است: State — شئ‌ای که یک بار ایجاد شده و از rebuildهای متعدد ویجت جان سالم به در می‌آید. وقتی وضعیت تغییر می‌کند (setState())، Flutter روش build() State را فراخوانده و UI را به‌روز می‌کند. StatefulWidget برای عناصر تعاملی استفاده می‌شود: شمارنده‌ها، فیلدهای متنی، کادرهای واردادی، انیمیشن‌ها، تایمرها.

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

class LikeButton extends StatefulWidget {
  const LikeButton({super.key});

  @override
  State<LikeButton> createState() => _LikeButtonState();
}

class _LikeButtonState extends State<LikeButton> {
  bool liked = false;
  int count = 42;

  void _toggleLike() {
    setState(() {
      liked = !liked;
      count += liked ? 1 : -1;
    });
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _toggleLike,
      child: Text(liked ? '♥ $count' : '♡ $count'),
    );
  }
}

LikeButton — StatefulWidget با کلاس State گیرندگی _LikeButtonState. خواص liked و count وضعیتی هستند که در State ذخیره می‌شوند و در rebuild بازنشسته نمی‌شوند. setState() به Flutter اطلاع می‌دهد که UI را بازسازی کند. Flutter State را در هر rebuild والد مجدداً ایجاد نمی‌کند — تنها در زمان تغییر پیکربندی (key یا نوع ویجت). در IT Sectr ما از StatelessWidget برای نمایش و از StatefulWidget برای کامپوننت‌های تعاملی استفاده می‌کنیم، با پیروی از اصل کاهش StatefulWidget تا حدود تغییر.

درخت ویجت‌ها: از Widget تا RenderObject

Widget Tree — ساختار سلسله‌مراتبی ویجت‌هایی که UI برنامه را توصیف می‌کند. Flutter Widget Tree را به Element Tree تبدیل می‌کند: هر Widget یک Element ایجاد می‌کند که موقعیت در درخت و ارتباط با RenderObject را پیگیری می‌کند. Render Tree layout (تعیین اندازه و موقعیت) و paint (رسم) را انجام می‌دهد. Element لایه کلیدی بهینه‌سازی است: اگر نوع ویجت و key در rebuild تغییر نکرده باشند، Element مجدداً استفاده می‌شود و پیکربندی را بدون ایجاد مجدد RenderObject به‌روز می‌کند. این عملکرد Flutter را در فرکانس بالای کادر (60/120 FPS) تضمین می‌کند.

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

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter Widgets')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Icon(Icons.flutter_dash, size: 80),
            const SizedBox(height: 16),
            const Text(
              'سلام، Flutter!',
              style: TextStyle(fontSize: 24),
            ),
          ],
        ),
      ),
    );
  }
}

درخت ویجت HomeScreen: Scaffold → AppBar + Center → Column → [Icon, SizedBox, Text]. Scaffold — ویجت layout اصلی Material Design. Center ویجت فرعی Column را وسط چین می‌کند. Column فرزندان را به صورت عمودی با تراز وسط (mainAxisAlignment.center) جایگذاری می‌کند. Flutter layout را از بالا به پایین (constraints از والد انتقال می‌یابند) و اندازه‌ها را از پایین به بالا (sizedByParent یا sizing from children) محاسبه می‌کند.

BuildContext: زمینه ساخت و دسترسی به درخت

BuildContext — دسکریپتور موقعیت ویجت در Element Tree. هر روش build() BuildContext را دریافت می‌کند که از طریق آن ویجت می‌تواند به موارد زیر دسترسی داشته باشد: MediaQuery (اندازه صفحه، جهت‌گیری، تراکم پیکسل، ناحیه امن), Theme (MaterialThemeData یا CupertinoThemeData), Navigator (پیشکه ناوبری), ScaffoldMessenger (SnackBar), InheritedWidget (انتقال داده به پایین درخت). BuildContext نباید پس از پایان build() ذخیره شود یا خارج از زمینه همگام استفاده شود — این به خطاهای «Scaffold.of() called with a context that does not contain a Scaffold» منجر می‌شود. به جای ذخیره context، از ویجت Builder یا الگوی InheritedWidget برای دسترسی به داده‌ها استفاده کنید.

Key: شناسایی ویجت در درخت

Key — پارامتر اختیاری سازنده هر ویجت (super.key). Key به Flutter در زمان تغییر ترتیب/تعداد عناصر در لیست در شناسایی ویجت کمک می‌کند. بدون key، Flutter ویجت‌ها را بر اساس نوع و موقعیت مقایسه می‌کند؛ در زمان افزودن عنصر به وسط لیست بدون key، Flutter از Element برای ویجت اشتباه مجدداً استفاده می‌کند و باعث خطاهای وضعیت (StatefulWidget) و انیمیشن می‌شود. برای لیست‌ها از ValueKey (شناسه یکتا)، ObjectKeyUniqueKey

(برای ایجاد مجدد اجباری) استفاده کنید.

کاتالوگ ویجت‌های Flutter: Material، Cupertino، Layout

Flutter SDK (نسخه پایدار 3.3+، Dart 3+) شامل 200+ ویجت ساخته شده است که به رده‌های زیر تقسیم شده‌اند: Layout (Row, Column, Stack, Container, Expanded, Flexible, Wrap, GridView, ListView, CustomScrollView)، Material Design (Scaffold, AppBar, Card, Drawer, BottomNavigationBar, FloatingActionButton, TabBar, Chip, DataTable)، Cupertino (CupertinoPageScaffold, CupertinoNavigationBar, CupertinoButton, CupertinoTabBar)، Painting & Effects (Opacity, DecoratedBox, ClipRect, Transform, BackdropFilter, ShaderMask)، Async (FutureBuilder, StreamBuilder) و Accessibility (Semantics, MergeSemantics, ExcludeSemantics). ویجت‌های Layout پایه هر Flutter UI هستند: Row برای توالی‌های افقی، Column برای عمودی، Stack برای عناصر متداخل، Container با BoxDecoration برای تزیین.

ردهویجت‌های کلیدیکاربرد
LayoutRow, Column, Stack, Container, Expanded, Flexibleموقعیت‌یابی و اندازه عناصر فرعی
MaterialScaffold, AppBar, Card, Drawer, FAB, TabBarکامپوننت‌های UI Material Design 3
CupertinoCupertinoPageScaffold, CupertinoNavigationBar, CupertinoButtonکامپوننت‌های به سبک iOS
PaintingOpacity, ClipRect, Transform, DecoratedBox, BackdropFilterافکت‌های دیداری و برش
AsyncFutureBuilder, StreamBuilderبارگیری ناهمگام داده با وضعیت‌های UI
AccessibilitySemantics, MergeSemanticsعلامت‌گذاری معنایی برای خواننده‌های صفحه

سوالات متداول

تفاوت StatelessWidget و StatefulWidget چیست؟

StatelessWidget وضعیت داخلی ندارد — همه داده‌ها از طریق سازنده انتقال می‌یابند و تغییر نمی‌کنند. StatefulWidget وضعیت تغییرپذیر را در شئ‌ء State جداگانه ذخیره می‌کند که از rebuildها جان سالم به در می‌آید. تغییر وضعیت setState() را فراخوانده و Flutter UI را بازسازی می‌کند. برای عناصر تغییرناپذیر از StatelessWidget و برای عناصر تعاملی از StatefulWidget استفاده کنید.

BuildContext در Flutter چیست؟

BuildContext — دسکریپتور موقعیت ویجت در Element Tree است که به روش build() انتقال می‌یابد. از طریق context، ویجت به MediaQuery، Theme، Navigator، ScaffoldMessenger و InheritedWidget دسترسی پیدا می‌کند. BuildContext نباید پس از پایان build() ذخیره شود. برای دسترسی به داده‌ها از ویجت Builder یا InheritedWidget استفاده کنید.

آیا برای کار با Flutter دانستن Dart ضروری است؟

بله، Flutter از Dart به عنوان تنها زبان برنامه‌نویسی استفاده می‌کند. Dart یک زبان با نوع‌بندی استاتیک با null-safety، انواع صوتی (sound null safety)، extension methods و pattern matching است. برای شروع اصولات Dart کافی است: کلاس‌ها، توابع، async/await، کلکشن‌ها. Dart به کد ناتیو (AOT) از طریق Dart Native و به JavaScript (برای وب) از طریق Dart2JS کامپایل می‌شود.

آیا Flutter تنها برای پلتفرم‌های موبایل است؟

خیر، Flutter از شش پلتفرم پشتیبانی می‌کند: iOS, Android, Web, macOS, Windows, Linux. بیش از 90% کد برای همه سیستم‌عامل‌ها مشترک است. سازگاری‌های سیستم‌عاملی (دوربین، فایل سیستم) از طریق افزونه‌ها یا platform channels اجرا می‌شوند. برای دسکتاپ، Flutter از پوشه پنجره Flutter Desktop و برای وب از موتور CanvasKit (WebGL) یا رندرکننده HTML استفاده می‌کند.

Flutter چگونه عملکرد 60 FPS را تأمین می‌کند؟

Flutter 60/120 FPS را به لطف موتور دوبعدی خود (Skia/Impeller)، نبود bridge سیستم‌عامل (بر خلاف React Native)، سه درخت (Widget → Element → Render) با استفاده مجدد از Element در صورت ثابت بودن نوع/key، الگوریتم layout با گذر یکطرفه (constraints down, sizes up) و RepaintBoundary برای جداسازی ترسیم مجدد نواحی مختلف صفحه به دست می‌آورد.

نتایج

  • Flutter Widgets — همه عناصر UI: از Scaffold تا SizedBox؛ Flutter آنها را خود در Skia/Impeller می‌کشد و از کامپوننت‌های سیستم‌عامل استفاده نمی‌کند.
  • StatelessWidget — ویجت بدون وضعیت؛ build() UI را بر اساس پارامترهای تغییرناپذیر سازنده بازمی‌گرداند.
  • StatefulWidget — ویجت با وضعیت تغییرپذیر در State؛ setState() باعث rebuild UI می‌شود.
  • سه درخت Flutter: Widget (پیکربندی) → Element (موقعیت) → Render (layout + paint)؛ Element برای عملکرد مجدداً استفاده می‌شود.
  • BuildContext — موقعیت ویجت در درخت؛ دسترسی به MediaQuery، Theme، Navigator، InheritedWidget.
  • Material و Cupertino — دو مجموعه ویجت برای Google Material Design 3 و Apple HIG.
  • Key (ValueKey, ObjectKey, UniqueKey) — شناسایی ویجت در زمان تغییر ترتیب/تعداد در لیست.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید