Azimjon Abdurasulov

Flutter 4: Flutter widgetlari SwiftUI dasturchisi uchun

💙 Flutter — Mobile (iOS, Android) & Desktop (macOS, Windows)

Flutter 4: Flutter widgetlari SwiftUI dasturchisi uchun

Holat: 2026-yil sentabr. SwiftUI va Flutter deklarativ UI tamoyillariga asoslangan bo'lib, ularning falsafasi juda yaqin. Ushbu darsda SwiftUI komponentlarining Flutter'dagi aniq ekvivalentlari (Row, Column, Stack, ListView), State boshqaruvi (setState vs @State), Material va Cupertino widgetlarining 3.47 dagi ajratilishi hamda to'liq amaliy ilova ko'rsatiladi.

Mundarija

  1. Widget daraxti va SwiftUI View falsafasi
  2. StatelessWidget va StatefulWidget (@State analogi)
  3. Maket (Layout) komponentlari: HStack/VStack/ZStack ekvivalentlari
  4. Ro'yxatlar: ListView.builder va virtualizatsiya
  5. Matn kiritish va formalar (TextField & Controller)
  6. Navigatsiya: Navigator va go_router
  7. Material va Cupertino'ning ajratilishi (Flutter 3.47)
  8. To'liq amaliy namuna: Rejalar ilovasi (TodoList)
  9. Xulosa
  10. Manbalar

1. Widget daraxti va SwiftUI View falsafasi](#widget-tree)

SwiftUI'da hamma narsa View protokoliga asoslanadi. Flutter'da esa shior: "Everything is a Widget" (Hamma narsa widget).

TushunchaSwiftUIFlutter
Interfeys blokistruct MyView: Viewclass MyWidget extends StatelessWidget
Chizish metodivar body: some View { ... }Widget build(BuildContext context) { ... }
Kontekst@EnvironmentBuildContext context (mavzu, o'lcham va ierarxiya kaliti)
Identifikator.id(...) yoki IdentifiableKey (masalan, ValueKey, UniqueKey)
Vizual tekshiruvSwiftUI PreviewsStateful Hot Reload (sub-sekundlik tezlik)

SwiftUI'dagi View struktura (value type) bo'lib, har yangilanishda tezda qayta yaratiladi. Flutter'da ham Widget engil konfiguratsiya ob'ektidir; uning ostida og'irroq Element va RenderObject daraxtlari mavjud.


2. StatelessWidget va StatefulWidget (@State analogi)](#state-widgets)

SwiftUI'da oddiy ko'rinish va holatli ko'rinish o'rtasida klass darajasida farq yo'q — @State qo'shilsa kifoya. Flutter'da esa ikkita alohida baza mavjud:

  • **StatelessWidget:** O'zgarmas (immutable) widget. Faqat tashqi parametrlarga bog'liq.
  • **StatefulWidget:** Ichki holatga (state) ega widget. Holat o'zgarganda setState(() { ... }) chaqiriladi va Flutter faqat kerakli qismni qayta chizadi.
import 'package:flutter/material.dart';

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

  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _counter = 0;

  void _increment() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _increment,
      child: Text('Bosildi: $_counter'),
    );
  }
}

3. Maket (Layout) komponentlari: HStack/VStack/ZStack ekvivalentlari](#layout)

SwiftUI dasturchisi uchun maket widgetlarining to'g'ridan-to'g'ri lug'ati:

VazifaSwiftUIFlutter
Gorizontal qatorHStack(spacing: 8) { ... }Row(children: [ ... ])
Vertikal ustunVStack(alignment: .leading) { ... }Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ ... ])
Ustma-ust qatlamZStack { ... }Stack(children: [ ... ])
Bo'sh joyni to'ldirishSpacer()Spacer() yoki Expanded(child: ...)
O'lcham berish.frame(width: 100, height: 50)SizedBox(width: 100, height: 50, child: ...)
Ichki oraliq.padding(16)Padding(padding: EdgeInsets.all(16), child: ...)

4. Ro'yxatlar: ListView.builder va virtualizatsiya](#lists)

Katta hajmdagi ma'lumotlarni ko'rsatishda SwiftUI'dagi LazyVStack yoki List kabi Flutter'da **ListView.builder** ishlatiladi. U faqat ekranda ko'rinib turgan elementlarni xotirada ushlaydi:

import 'package:flutter/material.dart';

Widget buildUserList(List<String> users) {
  return ListView.builder(
    itemCount: users.length,
    itemBuilder: (context, index) {
      return ListTile(
        title: Text(users[index]),
      );
    },
  );
}

5. Matn kiritish va formalar (TextField & Controller)](#forms)

SwiftUI'da TextField to'g'ridan-to'g'ri @State String ga @Binding bilan ulanadi ($text).

Flutter'da esa matn holatini boshqarish uchun **TextEditingController** ishlatiladi va xotira sizib chiqmasligi (memory leak) uchun u dispose() metodida yopilishi shart:

import 'package:flutter/material.dart';

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

  @override
  State<InputExample> createState() => _InputExampleState();
}

class _InputExampleState extends State<InputExample> {
  final TextEditingController _controller = TextEditingController();

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: _controller,
      decoration: const InputDecoration(labelText: 'Ismingiz'),
    );
  }
}

6. Navigatsiya: Navigator va go_router](#navigation)

Kichik ilovalarda imperativ Navigator.push(context, MaterialPageRoute(...)) ishlatiladi. Biroq, zamonaviy Flutter va Deep Linking talablari uchun rasmiy **go_router** (18.0.2) paketi standart hisoblanadi (go_router pub.dev):

  • SwiftUI'dagi NavigationStack va .navigationDestination(for:) kabi marshrutlarni deklarativ boshqaradi.
  • URL orqali navigatsiya (masalan, /profile/:id) va orqaga qaytish zanjirini osonlashtiradi.

7. Material va Cupertino'ning ajratilishi (Flutter 3.47)](#decoupling)

2026-yil 12-avgustda chiqqan Flutter 3.47 versiyasidan boshlab jiddiy me'moriy o'zgarish ro'y berdi: Google Material Design va Apple Cupertino uslubidagi widgetlarni asosiy Flutter freymvorkidan alohida mustaqil paketlarga ajratdi (Flutter Blog, 2026-09-09):

  • **material_ui (1.5.0):** Material 3 komponentlari.
  • **cupertino_ui (1.1.1):** iOS uslubidagi komponentlar.

Bu o'zgarish Flutter ilovalarining hajmini kichraytirish va Apple yoki Google o'z dizayn tizimini yangilaganda butun freymvorkni kutmasdan, faqat UI paketini yangilash imkonini beradi. Eskiroq kodlar uchun package:flutter/material.dart hanuz to'liq orqaga moslikni saqlab qolgan.


8. To'liq amaliy namuna: Rejalar ilovasi (TodoList)](#full-example)

Quyida vazifalarni qo'shish, bajarilgan deb belgilash va o'chirish imkonini beruvchi to'liq, mustaqil Flutter ilovasi keltirilgan:

import 'package:flutter/material.dart';

void main() => runApp(const TodoApp());

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: TodoListScreen(),
    );
  }
}

class TodoItem {
  final String id;
  final String title;
  bool isDone;

  TodoItem({required this.id, required this.title, this.isDone = false});
}

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

  @override
  State<TodoListScreen> createState() => _TodoListScreenState();
}

class _TodoListScreenState extends State<TodoListScreen> {
  final List<TodoItem> _todos = [];
  final TextEditingController _controller = TextEditingController();

  void _addTodo() {
    final text = _controller.text.trim();
    if (text.isEmpty) return;
    setState(() {
      _todos.add(TodoItem(
        id: DateTime.now().toIso8601String(),
        title: text,
      ));
      _controller.clear();
    });
  }

  void _toggleTodo(int index) {
    setState(() {
      _todos[index].isDone = !_todos[index].isDone;
    });
  }

  void _removeTodo(int index) {
    setState(() {
      _todos.removeAt(index);
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Vazifalar royxati')),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _controller,
                    decoration: const InputDecoration(
                      hintText: 'Yangi vazifa kiriting...',
                    ),
                  ),
                ),
                IconButton(
                  icon: const Icon(Icons.add),
                  onPressed: _addTodo,
                ),
              ],
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: _todos.length,
              itemBuilder: (context, index) {
                final todo = _todos[index];
                return ListTile(
                  leading: Checkbox(
                    value: todo.isDone,
                    onChanged: (_) => _toggleTodo(index),
                  ),
                  title: Text(
                    todo.title,
                    style: TextStyle(
                      decoration:
                          todo.isDone ? TextDecoration.lineThrough : null,
                    ),
                  ),
                  trailing: IconButton(
                    icon: const Icon(Icons.delete, color: Colors.red),
                    onPressed: () => _removeTodo(index),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

9. Xulosa {#xulosa}

  • SwiftUI'dagi deklarativ ko'nikmalar (HStack, VStack, ZStack) Flutter'da to'g'ridan-to'g'ri (Row, Column, Stack) qo'llanadi.
  • StatelessWidget statik ko'rinishlar uchun, StatefulWidget esa setState orqali yangilanuvchi dinamik interfeyslar uchun mo'ljallangan.
  • Resurslarni to'g'ri boshqarish uchun TextEditingController kabi boshqaruvchilar doimo dispose() metodida yopilishi shart.
  • Flutter 3.47 dan boshlab Material va Cupertino alohida paketlarga bo'lindi, bu ilova hajmini optimallashtiradi.
  • Katta loyihalarda marshrutlash uchun go_router eng qulay va zamonaviy yechimdir.

Manbalar {#manbalar}

  1. Flutter for SwiftUI Developers — Flutter Docs
  2. Decoupling Material and Cupertino — Flutter Blog (2026-09-09)
  3. go_router Package — pub.dev
  4. Building Layouts in Flutter — Flutter Docs

Markdown manba

iOS Lessons