Widget — Flutter frameworkunun mərkəzi anlayışıdır, istifadəçi interfeysi elementinin konfiqurasiyasını təsvir edir. Hər bir vizual komponent, düymədən mürəkkəb animasiyaya qədər, Widget-dir. Digər frameworklardan fərqli olaraq, UI ayrı XML faylları ilə təsvir edilir və ya imperativ şəkildə çəkilir, Flutter interfeysi Widget kompozisiyası — kiçik bölünməz elementlərin iyerarxik ağacda birləşdirilməsi ilə qurur. Flutter Documentation (2025)-ə görə, Flutter SDK kitabxanası Material Design, Cupertino və fərdi stilləri əhatə edən 260-dan çox daxili Widget daxildir.
Əsas məqamlar
Widget Flutter-də istifadəçi interfeysi hissəsinin dəyişməz (immutable) təsviridir. Hər bir Widget konfiqurasiya xüsusiyyətlərini ehtiva edir: ölçü, rəng, mövqe, mətn, hadisə idarəediciləri və uşaq Widget-lər. Widget-lər birbaşa render olunmur — onlar Flutter Engine-in RenderObject — ekranda real qrafik obyekt yaratdığı reseptlərdir (blueprints).
Flutter fəlsəfəsi deyir: “Everything is a Widget”. Bu o deməkdir ki, təkcə görünən elementlər (Text, Image, Button) deyil, həm də struktur blokları (Padding, Center, Column, Stack), davranış blokları (GestureDetector, AnimatedBuilder) və hətta tətbiqin özü (MaterialApp, CupertinoApp) Widget-dir. Bu yanaşma vahidliyi təmin edir: ekranın istənilən elementini sadə yerləşdirmə vasitəsilə hər hansı digəri ilə birləşdirmək olar.
Google I/O 2024 — Flutter Widgets Deep Dive məlumatlarına görə, Flutter-də orta tətbiq bir anda 200-dən 1500-ə qədər Widget ehtiva edir. Bu rəqəmə baxmayaraq, Flutter C++ Skia/Impeller engine səviyyəsində optimallaşdırmalar sayəsində hətta büdcə cihazlarında da 60 FPS qoruyur. Widget yüngül obyektlərdir (hər biri 40–80 bayt), buna görə də onların yaradılması performans darboğazı deyil.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Center(
child: Text('Salam, Flutter!'),
),
),
);
}
}
Widget-in necə işlədiyini anlamaq üçün üç əlaqəli ağacdan ibarət Flutter arxitekturasını başa düşmək lazımdır. Birinci — Widget tree — UI konfiqurasiyasını təsvir edir. Bu yüngül ağacdır, hər kadrda tamamilə yenidən qurula bilər (garbage collector köhnə Widget-ləri silir və yenilərini yaradır). Widget-lər dəyişməzdir (immutable): mətn rəngi dəyişibsə — yeni rənglə yeni Text Widget yaradılır, köhnəsi atılır.
İkinci ağac — Element tree — Widget və RenderObject arasında əlaqələndirici halqadır. Element Widget (konfiqurasiya) və RenderObject (render) istinadını ehtiva edir. Widget dəyişdikdə, Flutter yeni Widget-i köhnə Element ilə müqayisə edir və qərar verir: mövcud RenderObject-i yeniləmək (Widget eyni tipdədirsə) və ya yenisini yaratmaq (Widget tipi dəyişibsə). Bu proses Reconciliation adlanır və React Virtual DOM-un analoqudur.
Üçüncü ağac — RenderObject tree — ekranda real renderə cavabdehdir. RenderObject konkret ölçülər, mövqelər və paint metodlarını ehtiva edir. Flutter Engine (C++ Skia və ya Impeller) RenderObject tree üzərində hərəkət edir və hər bir düyünü render edir. RenderObject tree ən ağır ağacdır, buna görə Flutter eyni tipli Widget dəyişdirilərkən RenderObject-i təkrar istifadə edərək onun dəyişikliklərini minimuma endirir.
| Ağac | Təyinat | Immutable? | Həyat dövrü |
|---|---|---|---|
| Widget | UI konfiqurasiyası (resept) | Bəli | Hər build-də yenidən yaradılır |
| Element | Widget ↔ RenderObject əlaqəsi | Xeyr | Vidjet ağacda olduğu müddətcə mövcuddur |
| RenderObject | Render və layout | Xeyr | Ağır, mümkün olduqda təkrar istifadə olunur |
Flutter Widget-ləri iki əsas tipə bölür: StatelessWidget və StatefulWidget. StatelessWidget dəyişən vəziyyəti olmayan vidjetdir. StatelessWidget-in görünüşü tamamilə onun konstruktoru ilə müəyyən edilir və renderdən sonra dəyişə bilməz. Nümunələr: Text, Icon, Divider, Padding. StatelessWidget-in bütün xüsusiyyətləri konstruktorda final olaraq elan edilir və yalnız oxumaq üçün əlçatandır.
StatefulWidget dəyişən vəziyyətə malik vidjetdir. O, iki sinifdən ibarətdir: Widget-in özü (StatelessWidget kimi dəyişməz konfiqurasiya) və State (dəyişən vəziyyət). Widget-in State-dən ayrılması Flutter-in əsas arxitektura qərarıdır. Widget hər build-də yenidən yaradılır, lakin State obyekti vidjetin ağacdakı bütün həyat dövrü ərzində yaşayır, vəziyyətini qoruyur.
setState() çağırıldıqda, Flutter State-i “cirklu” olaraq qeyd edir və növbəti kadrda alt ağacı yenidən qurmaq üçün build() metodunu çağırır. Vacib: setState() Widget-in özünü yenidən yaratmır — o, yalnız mövcud State-də build() çağırışını tetikler. Bu o deməkdir ki, StatefulWidget uşaq elementlərinin açarları (Key) sabit qaldığı müddətcə uşaq Widget-lərin vəziyyətini itirmədən UI-ni yeniləyə bilər.
// StatelessWidget — görünüş heç vaxt dəyişmir
class GreetingWidget extends StatelessWidget {
const GreetingWidget({super.key, required this.name});
final String name;
@override
Widget build(BuildContext context) {
return Text('Salam, $name');
}
}
// StatefulWidget — dəyişən vəziyyətə malik sayğac
class CounterWidget extends StatefulWidget {
const CounterWidget({super.key});
@override
State<CounterWidget> createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Sayğac: $_count'),
ElevatedButton(
onPressed: () => setState(() => _count++),
child: const Text('Artır'),
),
],
);
}
}
Flutter-də bütün Widget funksional təyinatına görə üç əsas kateqoriyaya bölünə bilər. Layout Widget — uşaq elementlərinin ekranda yerləşməsinə cavabdehdir. Row və Column uşaqları xətt üzrə yerləşdirir, Stack birini digərinin üstünə qoyur, Expanded və Flexible mövcud yeri bölüşdürür. Layout Widget-lərin öz vizual təsviri yoxdur — onlar uşaq vidjetlərin mövqeyini və ölçüsünü idarə edir.
Painting Widget — vizual tərtibata cavabdehdir. Container dekorasiyaları (rəng, gradient, kölgə, haşiyə) layout xüsusiyyətləri ilə birləşdirir. Padding boşluqlar əlavə edir, DecoratedBox fon çəkir, Transform çevirmələr tətbiq edir (döndərmə, miqyaslama). Painting Widget vizual stil tikinti bloklarıdır və istədiyiniz görünüşü əldə etmək üçün tez-tez layout Widget ilə birlikdə istifadə olunur.
Interactive Widget — istifadəçi girişini emal edir. GestureDetector jestləri müəyyən edir (tap, swipe, pinch), InkWell Material ripple-effekti əlavə edir, TextField mətn daxil edir, Slider və Switch standart idarəetmə elementləri təqdim edir. Interactive Widget hadisələri konstruktora ötürülən və ya vəziyyət təminatçıları vasitəsilə idarə olunan callback funksiyaları vasitəsilə qaldırır.
| Kateqoriya | Widget nümunələri | Təyinat |
|---|---|---|
| Layout | Row, Column, Stack, Expanded, Flexible, Align | Uşaq elementlərin yerləşməsi və ölçüsü |
| Painting | Container, Padding, DecoratedBox, RotatedBox | Rəng, fon, haşiyələr, kölgələr, çevirmələr |
| Interactive | GestureDetector, InkWell, TextField, Slider | Toxunma, daxiletmə, jest emalı |
| Platform | MaterialApp, CupertinoApp, Theme, MediaQuery | Platforma ilə inteqrasiya, mövzular, adaptasiya |
| Async | FutureBuilder, StreamBuilder, ValueListenableBuilder | Asinxron məlumatlardan reaktiv yeniləmə |
Flutter Widget of the Week (Google, 2025) məlumatlarına görə, Flutter icması demək olar ki, hər hansı interfeysi qurmaq üçün layout + painting + interactive Widget kombinasiyasından fəal istifadə edir. Məsələn, düymə: InkWell (interactive) + Container (painting) + Text (static) + Padding (layout). Bu modulluq standart blokları kod təkrarlamadan müxtəlif kontekstlərdə təkrar istifadə etməyə imkan verir.
Widget kompozisiyası — UI-nin bəzi Widget-lərin digərlərinə yerləşdirilməsi yolu ilə qurulması prosesidir. Klassik miras almadan (extends) fərqli olaraq, burada uşaq sinif valideynin davranışını miras alır, Flutter aqreqasiyadan istifadə edir: hər bir Widget digər Widget-ləri child (bir üçün) və ya children (çox üçün) parametri vasitəsilə ehtiva edir. Bu yanaşma daha çox çeviklik və təkrar istifadə imkanı verir.
BuildContext Widget-dən sonra ikinci ən vacib anlayışdır. BuildContext — Widget-in elementlər ağacındakı mövqeyinin deskriptorudur. BuildContext vasitəsilə Widget əcdad vidjetlərinə (Theme.of(context), MediaQuery.of(context), Navigator.of(context)) müraciət edə bilər. BuildContext build() metoduna ötürülür və valideyn və uşaq elementləri ilə qarşılıqlı əlaqə üçün istifadə olunur. Hər bir Widget-in onun ağacdakı mövqeyini unikal şəkildə müəyyən edən bir BuildContext-i var.
Flutter Architectural Overview (Google, 2025)-ə görə, BuildContext InheritedWidget üçün əsasdır — konstruktorlar vasitəsilə açıq ötürmədən məlumatları ağacda aşağı ötürməyə imkan verən mexanizm. Theme, MediaQuery, Navigator və Provider InheritedWidget-dən istifadə edir. Hər bir dərin yerləşdirilmiş Widget BuildContext.dependOnInheritedWidgetOfExactType vasitəsilə əcdad məlumatlarına daxil ola bilər ki, bu da BuildContext-i Flutter-in reaktiv arxitekturasının açarına çevirir.
// Widget kompozisiyası yerləşdirmə yolu ilə
Scaffold(
appBar: AppBar(title: const Text('Mənim Tətbiqim')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Flutter-ə xoş gəlmisiniz',
style: TextStyle(fontSize: 24)),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () { /* nav */ },
child: const Text('Başlayın'),
),
],
),
),
)
// BuildContext vasitəsilə mövzulara giriş
Text(
'Stilləndirilmiş Mətn',
style: Theme.of(context).textTheme.headlineMedium,
)
Birinci və ən ümumi səhv — StatelessWidget-in kifayət etdiyi yerdə StatefulWidget istifadə etmək. Bir çox başlanğıc Flutter tərtibatçıları bütün vidjetlər üçün StatefulWidget yaradır, hətta vəziyyət xarici təminatçıda (Provider, Riverpod, BLoC) saxlanılsa belə. Bu lazımsızdır və performansı pisləşdirir. Qayda: vəziyyət xaricdən idarə olunursa və ya vidjetin öz dəyişən vəziyyəti yoxdursa, StatelessWidget istifadə edin.
İkinci səhv — build metodu daxilində const-konstruktorsuz Widget yaratmaq. Const olmadan yaradılan hər bir Widget hər build-də yenidən ayrılır. build() daxilində Widget-ləri const-konstruktorla yaratmaqla Flutter eyni nümunəni təkrar istifadə edə bilər, garbage collector yükünü azaldır. Mümkün olan hər yerdə const əlavə edin — xüsusən Text, Icon, SizedBox, Padding və digər stateless Widget-lər üçün.
Üçüncü səhv — açarlarla (Key) səhv işləmək. Flutter ağacı yenidən qurarkən Widget-i müəyyən etmək üçün Key-dən istifadə edir. Widget siyahısı Key olmadan yenidən qurularsa, Flutter elementlərin sırasını qarışdıra bilər ki, bu da səhv animasiyaya və ya vəziyyət itkisinə səbəb olur. Xüsusilə dinamik məlumatlarla ListView.builder istifadə edərkən siyahılardakı elementlər üçün həmişə Key (məsələn, ValueKey və ya ObjectKey) əlavə edin.
Tez-tez verilən suallar
StatelessWidget — dəyişən vəziyyəti olmayan vidjet, onun görünüşü tamamilə konstruktor tərəfindən müəyyən edilir. StatefulWidget — dəyişən vəziyyətə malik vidjet, vəziyyət ayrıca State obyektində saxlanılır və setState() vasitəsilə vidjetin özünü yenidən yaratmadan yenilənə bilər. Mümkün olan yerdə StatelessWidget, lokal vəziyyət tələb olunduqda StatefulWidget istifadə edin.
Widget immutable — bu Flutter-in performans üçün arxitektura qərarıdır. Əgər Widget mutable olsaydı, Flutter hər build-də köhnə və yeni konfiqurasiyanı təhlükəsiz şəkildə müqayisə edə bilməzdi. Immutability Flutter-ə Widget-in dəyişib-dəyişmədiyini (== operatoru vasitəsilə) tez müəyyən etməyə və mövcud RenderObject-i təkrar istifadə edərək bahalı render əməliyyatlarını minimuma endirməyə imkan verir.
BuildContext — Widget-in elementlər ağacındakı mövqeyinin deskriptorudur. Onun vasitəsilə Widget əcdad vidjetlərinə (Theme, MediaQuery, Navigator) və InheritedWidget-ə daxil ola bilər. BuildContext həmçinin naviqasiya (Navigator.of(context)), SnackBar göstərmək və Provider ilə qarşılıqlı əlaqə üçün istifadə olunur. Hər bir Widget build() metodu vasitəsilə BuildContext alır və onu varislərinə ötürür.
Elementlərin üfüqi yerləşməsi üçün Row, şaquli yerləşməsi üçün Column, elementlərin bir-birinin üstünə qoyulması üçün Stack istifadə edin. Row və Column flexbox prinsipi ilə işləyir: children mainAxisSize, mainAxisAlignment və crossAxisAlignment-a uyğun olaraq yer tutur. Stack kənarlara və ya mərkəzə nisbətən dəqiq yerləşdirmə üçün positioned-children istifadə edir.
Flutter yüksək performansa üç mexanizm vasitəsilə nail olur: (1) Widget are cheap — yüngül immutable obyektlər (40–80 bayt), onların yaradılması GC-ni yükləmir. (2) RenderObject reuse — eyni tipli Widget dəyişdirilərkən RenderObject təkrar istifadə edilir, bahalı yenidən yaratmanın qarşısı alınır. (3) Skia/Impeller engine — repaint boundaries vasitəsilə çağırışları minimuma endirməklə C++ səviyyəsində render.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun