Widget — یہ کیا ہے، اقسام اور Flutter میں ساخت

مصنف: IT Sectr اشاعت: 2026-06-30 مطالعے کا وقت: 10 منٹ

Widget Flutter فریم ورک کا مرکزی تصور ہے، جو یوزر انٹرفیس عنصر کی ترتیب کو بیان کرتا ہے۔ بٹن سے لے کر پیچیدہ اینیمیشن تک ہر بصری جزو ایک Widget ہے۔ دوسرے فریم ورکس کے برعکس جہاں UI کو علیحدہ XML فائلوں میں بیان کیا جاتا ہے یا لازمی طور پر پینٹ کیا جاتا ہے، Flutter Widget کمپوزیشن — چھوٹے ناقابل تقسیم عناصر کو ایک درجہ بندی کے درخت میں ملا کر — کے ذریعے انٹرفیس بناتا ہے۔ Flutter دستاویزات (2025) کے مطابق، Flutter SDK لائبریری میں Material Design، Cupertino اور کسٹم اسٹائلز کو کور کرنے والے 260 سے زیادہ بلٹ ان Widgets شامل ہیں۔

اہم نکات

  • Widget — Flutter میں UI کا بنیادی تعمیراتی بلاک، عنصر کی ترتیب کو بیان کرتا ہے۔
  • کمپوزیشن — UI وراثت کے ذریعے نہیں، بلکہ Widgets کو ایک دوسرے کے اندر نیسٹ کرکے بنایا جاتا ہے۔
  • StatelessWidget — ایک ویجیٹ جو رینڈر کرنے کے بعد تبدیل نہیں ہوتا (متن، آئیکن، پیڈنگ)۔
  • StatefulWidget — قابل تبدیل حالت والا ویجیٹ (فارم، اینیمیشن، ڈیٹا کی فہرستیں)۔
  • Element tree — Flutter تین درختوں کو برقرار رکھتا ہے: Widget، Element اور RenderObject۔

Flutter میں Widget کیا ہے

Flutter میں ایک Widget یوزر انٹرفیس کے ایک حصے کا ناقابل تبدیلی (immutable) بیان ہے۔ ہر Widget میں ترتیب کی خصوصیات ہوتی ہیں: سائز، رنگ، مقام، متن، ایونٹ ہینڈلر اور چائلڈ Widgets۔ Widgets براہ راست رینڈر نہیں ہوتے — یہ بلیو پرنٹس ہیں جن کی بنیاد پر Flutter Engine ایک RenderObject بناتا ہے، جو اسکرین پر اصل گرافیکل آبجیکٹ ہے۔

Flutter کا فلسفہ کہتا ہے: “Everything is a Widget”۔ اس کا مطلب ہے کہ نہ صرف نظر آنے والے عناصر (Text, Image, Button) Widgets ہیں، بلکہ ساختی بلاکس (Padding, Center, Column, Stack)، رویاتی بلاکس (GestureDetector, AnimatedBuilder) اور یہاں تک کہ خود ایپلیکیشن (MaterialApp, CupertinoApp) بھی Widgets ہیں۔ یہ طریقہ کار یکسانیت کو یقینی بناتا ہے: کسی بھی اسکرین عنصر کو سادہ نیسٹنگ کے ذریعے کسی دوسرے عنصر کے ساتھ جوڑا جا سکتا ہے۔

Google I/O 2024 — Flutter Widgets Deep Dive کے مطابق، Flutter پر اوسط ایپلیکیشن میں کسی بھی وقت 200 سے 1500 Widgets ہوتے ہیں۔ اس مقدار کے باوجود، Flutter C++ Skia/Impeller انجن کی سطح پر اصلاحات کی بدولت بجٹ والے آلات پر بھی 60 FPS برقرار رکھتا ہے۔ Widgets ہلکی آبجیکٹ ہیں (ہر ایک 40–80 بائٹس)، اس لیے ان کا بنانا کارکردگی کی رکاوٹ نہیں ہے۔

dart
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('ہیلو، Flutter!'),
        ),
      ),
    );
  }
}

Flutter کے تین درخت: Widget، Element اور RenderObject

یہ سمجھنے کے لیے کہ Widget کیسے کام کرتا ہے، تین باہم جڑے درختوں پر مشتمل Flutter فن تعمیر کو سمجھنا ضروری ہے۔ پہلا — Widget درخت — UI ترتیب کو بیان کرتا ہے۔ یہ ایک ہلکا درخت ہے جو ہر فریم پر مکمل طور پر دوبارہ تعمیر کیا جا سکتا ہے (کچرا جمع کرنے والا پرانے Widgets کو ہٹاتا ہے اور نئے بناتا ہے)۔ Widgets ناقابل تبدیلی (immutable) ہیں: اگر متن کا رنگ بدلتا ہے تو نئے رنگ کے ساتھ ایک نیا Text Widget بنایا جاتا ہے، پرانا چھوڑ دیا جاتا ہے۔

دوسرا درخت — Element درخت — Widget اور RenderObject کے درمیان رابطہ ہے۔ Element میں Widget (ترتیب) اور RenderObject (رینڈرنگ) کا حوالہ ہوتا ہے۔ جب Widget بدلتا ہے، Flutter نئے Widget کا پرانے Element سے موازنہ کرتا ہے اور فیصلہ کرتا ہے: موجودہ RenderObject کو اپ ڈیٹ کرے (اگر Widget ایک ہی قسم کا ہے) یا نیا بنائے (اگر Widget کی قسم بدل گئی ہے)۔ اس عمل کو Reconciliation کہا جاتا ہے اور یہ React Virtual DOM سے مشابہ ہے۔

تیسرا درخت — RenderObject درخت — اسکرین پر اصل رینڈرنگ کا ذمہ دار ہے۔ RenderObject میں مخصوص سائز، مقامات اور پینٹ کے طریقے ہوتے ہیں۔ Flutter Engine (C++ Skia یا Impeller) RenderObject درخت کو عبور کرتا ہے اور ہر نوڈ کو رینڈر کرتا ہے۔ RenderObject درخت سب سے بھاری درخت ہے، اس لیے Flutter ایک ہی قسم کے Widget پر سوئچ کرتے وقت RenderObjects کو دوبارہ استعمال کرکے اپنی تبدیلیوں کو کم سے کم کرتا ہے۔

درختمقصدناقابل تبدیلی؟زندگی کا دور
WidgetUI ترتیب (بلیو پرنٹ)ہاںہر build پر دوبارہ بنایا جاتا ہے
ElementWidget ↔ RenderObject لنکنہیںجب تک ویجیٹ درخت میں ہے موجود رہتا ہے
RenderObjectرینڈرنگ اور لے آؤٹنہیںبھاری، جب ممکن ہو دوبارہ استعمال ہوتا ہے

StatelessWidget بمقابلہ StatefulWidget

Flutter Widgets کو دو بنیادی اقسام میں تقسیم کرتا ہے: StatelessWidget اور StatefulWidget۔ StatelessWidget ایک ویجیٹ ہے جس میں قابل تبدیل حالت نہیں ہوتی۔ StatelessWidget کی ظاہری شکل مکمل طور پر اس کے کنسٹرکٹر سے متعین ہوتی ہے اور رینڈر کرنے کے بعد تبدیل نہیں ہو سکتی۔ مثالیں: Text, Icon, Divider, Padding۔ StatelessWidget کی تمام خصوصیات کنسٹرکٹر میں final کے طور پر اعلان کی جاتی ہیں اور صرف پڑھنے کے قابل ہوتی ہیں۔

StatefulWidget قابل تبدیل حالت والا ایک ویجیٹ ہے۔ یہ دو کلاسوں پر مشتمل ہے: Widget خود (StatelessWidget کی طرح ناقابل تبدیلی ترتیب) اور State (قابل تبدیل حالت)۔ Widget کو State سے الگ کرنا Flutter میں ایک اہم آرکیٹیکچرل فیصلہ ہے۔ Widget ہر build پر دوبارہ بنایا جاتا ہے، لیکن State آبجیکٹ درخت میں ویجیٹ کی پوری زندگی کے دوران زندہ رہتا ہے، اپنی حالت برقرار رکھتا ہے۔

جب setState() کو کال کیا جاتا ہے، Flutter State کو “گندا” نشان زد کرتا ہے اور اگلے فریم میں ذیلی درخت کو دوبارہ تعمیر کرنے کے لیے build() طریقہ کال کرتا ہے۔ اہم: setState() Widget خود دوبارہ نہیں بناتا — یہ صرف موجودہ State پر build() کال کو متحرک کرتا ہے۔ اس کا مطلب ہے کہ StatefulWidget چائلڈ Widgets کی حالت کھونے کے بغیر UI کو اپ ڈیٹ کر سکتا ہے، جب تک چائلڈ عناصر کی کنجیاں (Key) مستحکم رہیں۔

dart
// StatelessWidget — ظاہری شکل کبھی نہیں بدلتی
class GreetingWidget extends StatelessWidget {
  const GreetingWidget({super.key, required this.name});
  final String name;

  @override
  Widget build(BuildContext context) {
    return Text('ہیلو، $name');
  }
}

// StatefulWidget — قابل تبدیل حالت والا کاؤنٹر
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('گنتی: $_count'),
        ElevatedButton(
          onPressed: () => setState(() => _count++),
          child: const Text('بڑھائیں'),
        ),
      ],
    );
  }
}

Widget کی اقسام: layout، painting، interactive

Flutter میں تمام Widgets کو فعال مقصد کے مطابق تین اہم زمروں میں تقسیم کیا جا سکتا ہے۔ Layout Widgets — اسکرین پر چائلڈ عناصر کی پوزیشننگ کے ذمہ دار ہیں۔ Row اور Column بچوں کو ایک لائن میں ترتیب دیتے ہیں، Stack ایک کو دوسرے کے اوپر رکھتا ہے، Expanded اور Flexible دستیاب جگہ تقسیم کرتے ہیں۔ Layout Widgets کا اپنا کوئی بصری نمائندہ نہیں ہوتا — یہ چائلڈ ویجیٹس کی پوزیشن اور سائز کا انتظام کرتے ہیں۔

Painting Widgets — بصری اسٹائلنگ کے ذمہ دار ہیں۔ Container سجاوٹ (رنگ، گریڈینٹ، سایہ، بارڈر) کو لے آؤٹ خصوصیات کے ساتھ جوڑتا ہے۔ Padding فاصلہ شامل کرتا ہے، DecoratedBox پس منظر کھینچتا ہے، Transform تبدیلیاں (گھماؤ، پیمانہ) لاگو کرتا ہے۔ Painting Widgets بصری اسٹائل کے تعمیراتی بلاکس ہیں اور اکثر مطلوبہ ظاہری شکل حاصل کرنے کے لیے Layout Widgets کے ساتھ استعمال ہوتے ہیں۔

Interactive Widgets — صارف کے ان پٹ کو ہینڈل کرتے ہیں۔ GestureDetector اشاروں (ٹیپ، سوائپ، پنچ) کا پتہ لگاتا ہے، InkWell Material ریپل اثر شامل کرتا ہے، TextField متن ان پٹ قبول کرتا ہے، Slider اور Switch معیاری کنٹرول عناصر فراہم کرتے ہیں۔ Interactive Widgets کال بیک فنکشنز کے ذریعے ایونٹس کو اٹھاتے ہیں جو کنسٹرکٹر کو بھیجے جاتے ہیں یا ریاست فراہم کرنے والوں کے ذریعے ہینڈل کیے جاتے ہیں۔

زمرہWidget کی مثالیںمقصد
LayoutRow, Column, Stack, Expanded, Flexible, Alignچائلڈ عناصر کی پوزیشننگ اور سائز
PaintingContainer, Padding, DecoratedBox, RotatedBoxرنگ، پس منظر، بارڈرز، سائے، تبدیلیاں
InteractiveGestureDetector, InkWell, TextField, Sliderچھونے، ان پٹ، اشاروں کو ہینڈل کرنا
PlatformMaterialApp, CupertinoApp, Theme, MediaQueryپلیٹ فارم انضمام، تھیمز، موافقت
AsyncFutureBuilder, StreamBuilder, ValueListenableBuilderغیر ہم آہنگ ڈیٹا سے رد عمل اپ ڈیٹ

Flutter Widget of the Week (Google, 2025) کے مطابق، Flutter کمیونٹی عملی طور پر کسی بھی انٹرفیس کو بنانے کے لیے layout + painting + interactive Widgets کے امتزاج کو فعال طور پر استعمال کرتی ہے۔ مثال کے طور پر، ایک بٹن: InkWell (interactive) + Container (painting) + Text (static) + Padding (layout)۔ یہ ماڈیولریٹی کوڈ کی نقل کے بغیر مختلف سیاق و سباق میں معیاری بلاکس کو دوبارہ استعمال کرنے کی اجازت دیتی ہے۔

Widget کمپوزیشن اور BuildContext

Widget کمپوزیشن کچھ Widgets کو دوسروں کے اندر نیسٹ کرکے UI بنانے کا عمل ہے۔ کلاسیکی وراثت (extends) کے برعکس، جہاں چائلڈ کلاس والدین کے رویے کو حاصل کرتی ہے، Flutter اجتماع کا استعمال کرتا ہے: ہر Widget میں child پیرامیٹر (ایک کے لیے) یا children (کئی کے لیے) کے ذریعے دوسرے Widgets شامل ہوتے ہیں۔ یہ طریقہ کار زیادہ لچک اور دوبارہ استعمال کی صلاحیت فراہم کرتا ہے۔

BuildContext Widget کے بعد دوسرا سب سے اہم تصور ہے۔ BuildContext عنصر کے درخت میں Widget کی پوزیشن کا وصف کنندہ ہے۔ BuildContext کے ذریعے، Widget آباء ویجیٹس (Theme.of(context), MediaQuery.of(context), Navigator.of(context)) تک رسائی حاصل کر سکتا ہے۔ BuildContext build() طریقہ کو بھیجا جاتا ہے اور والدین اور چائلڈ عناصر کے ساتھ تعامل کے لیے استعمال ہوتا ہے۔ ہر Widget کے پاس بالکل ایک BuildContext ہوتا ہے، جو درخت میں اس کی پوزیشن کی منفرد شناخت کرتا ہے۔

Flutter Architectural Overview (Google, 2025) کے مطابق، BuildContext InheritedWidget کی بنیاد ہے — ایک طریقہ کار جو کنسٹرکٹرز کے ذریعے واضح منتقلی کے بغیر درخت میں نیچے ڈیٹا منتقل کرنے کی اجازت دیتا ہے۔ Theme، MediaQuery، Navigator اور Provider اندرونی طور پر InheritedWidget استعمال کرتے ہیں۔ کوئی بھی گہرائی سے نیسٹڈ Widget BuildContext.dependOnInheritedWidgetOfExactType کے ذریعے آباء ڈیٹا تک رسائی حاصل کر سکتا ہے، جو BuildContext کو Flutter کے رد عمل آرکیٹیکچر کی کنجی بناتا ہے۔

dart
// نیسٹنگ کے ذریعے Widget کمپوزیشن
Scaffold(
  appBar: AppBar(title: const Text('میری ایپ')),
  body: Center(
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        const Text('Flutter میں خوش آمدید',
          style: TextStyle(fontSize: 24)),
        const SizedBox(height: 16),
        ElevatedButton(
          onPressed: () { /* nav */ },
          child: const Text('شروع کریں'),
        ),
      ],
    ),
  ),
)

// BuildContext کے ذریعے تھیمز تک رسائی
Text(
  'اسٹائل شدہ متن',
  style: Theme.of(context).textTheme.headlineMedium,
)

Widget کے ساتھ عام غلطیاں

پہلی اور سب سے عام غلطی ہے وہاں StatefulWidget استعمال کرنا جہاں StatelessWidget کافی ہے۔ بہت سے ابتدائی Flutter ڈویلپر تمام ویجیٹس کے لیے StatefulWidget بناتے ہیں، یہاں تک کہ جب حالت بیرونی فراہم کنندہ (Provider, Riverpod, BLoC) میں محفوظ ہو۔ یہ بے جا ہے اور کارکردگی کو خراب کرتا ہے۔ قاعدہ: StatelessWidget استعمال کریں اگر حالت بیرونی طور پر منظم کی جاتی ہے یا اگر ویجیٹ کی اپنی قابل تبدیل حالت نہیں ہے۔

دوسری غلطی — const کنسٹرکٹر کے بغیر build طریقہ کے اندر Widget بنانا۔ const کے بغیر بنایا گیا ہر Widget ہر build پر دوبارہ مختص ہوتا ہے۔ اگر آپ build() کے اندر const کنسٹرکٹر کے ساتھ Widgets بناتے ہیں، Flutter ایک ہی مثال کو دوبارہ استعمال کر سکتا ہے، کچرا جمع کرنے والے پر بوجھ کم کرتا ہے۔ جہاں بھی ممکن ہو const شامل کریں — خاص طور پر Text, Icon, SizedBox, Padding اور دیگر بغیر حالت والے Widgets کے لیے۔

تیسری غلطی — کنجیوں (Key) کے ساتھ غلط کام کرنا۔ Flutter درخت کی دوبارہ تعمیر کے وقت Widgets کی شناخت کے لیے Key استعمال کرتا ہے۔ اگر Widgets کی فہرست Key کے بغیر دوبارہ تعمیر کی جاتی ہے، Flutter عناصر کی ترتیب کو الجھا سکتا ہے، جس سے غلط اینیمیشن یا حالت کا نقصان ہوتا ہے۔ فہرستوں میں عناصر کے لیے ہمیشہ Key (مثلاً ValueKey یا ObjectKey) شامل کریں، خاص طور پر متحرک ڈیٹا کے ساتھ ListView.builder استعمال کرتے وقت۔

اکثر پوچھے گئے سوالات

StatelessWidget اور StatefulWidget میں کیا فرق ہے؟

StatelessWidget — قابل تبدیل حالت کے بغیر ویجیٹ، اس کی ظاہری شکل مکمل طور پر کنسٹرکٹر سے متعین ہوتی ہے۔ StatefulWidget — قابل تبدیل حالت والا ویجیٹ، جو علیحدہ State آبجیکٹ میں محفوظ ہوتی ہے اور ویجیٹ کو دوبارہ بنائے بغیر setState() کے ذریعے اپ ڈیٹ کی جا سکتی ہے۔ جہاں ممکن ہو StatelessWidget استعمال کریں، StatefulWidget — جب مقامی حالت کی ضرورت ہو۔

Widgets کو ناقابل تبدیلی (immutable) کیوں کہا جاتا ہے؟

Widgets کی ناقابل تبدیلی کارکردگی کے لیے Flutter کا آرکیٹیکچرل فیصلہ ہے۔ اگر Widgets قابل تبدیلی ہوتے، Flutter ہر build پر پرانی اور نئی ترتیبات کا محفوظ طریقے سے موازنہ نہیں کر سکتا تھا۔ ناقابل تبدیلی Flutter کو تیزی سے یہ تعین کرنے کی اجازت دیتی ہے کہ آیا Widget تبدیل ہوا ہے (== آپریٹر کے ذریعے) اور موجودہ RenderObject کو دوبارہ استعمال کرتی ہے، مہنگی رینڈرنگ کارروائیوں کو کم سے کم کرتی ہے۔

BuildContext کیا ہے اور اس کی ضرورت کیوں ہے؟

BuildContext عنصر کے درخت میں Widget کی پوزیشن کا وصف کنندہ ہے۔ اس کے ذریعے، Widget آباء ویجیٹس (Theme, MediaQuery, Navigator) اور InheritedWidget تک رسائی حاصل کرتا ہے۔ BuildContext نیویگیشن (Navigator.of(context))، SnackBar دکھانے اور Provider کے ساتھ تعامل کے لیے بھی استعمال ہوتا ہے۔ ہر Widget build() طریقہ کے ذریعے BuildContext حاصل کرتا ہے اور اسے اولاد کو منتقل کرتا ہے۔

لے آؤٹ کے لیے Row، Column اور Stack کے درمیان کیسے انتخاب کریں؟

عناصر کی افقی ترتیب کے لیے Row، عمودی ترتیب کے لیے Column، عناصر کو ایک دوسرے کے اوپر رکھنے کے لیے Stack استعمال کریں۔ Row اور Column flexbox اصول پر کام کرتے ہیں: بچے mainAxisSize، mainAxisAlignment اور crossAxisAlignment کے مطابق جگہ گھیرتے ہیں۔ Stack کناروں یا مرکز کے نسبت درست پوزیشننگ کے لیے پوزیشن والے بچوں کا استعمال کرتا ہے۔

Flutter ہزاروں Widgets کے ساتھ 60 FPS کیسے برقرار رکھتا ہے؟

Flutter تین میکانزم کے ذریعے اعلی کارکردگی حاصل کرتا ہے: (1) Widgets سستے ہیں — ہلکی ناقابل تبدیلی آبجیکٹ (40–80 بائٹس)، ان کا بنانا GC پر بوجھ نہیں ڈالتا۔ (2) RenderObject دوبارہ استعمال — ایک ہی قسم کے Widget پر سوئچ کرتے وقت RenderObject دوبارہ استعمال ہوتا ہے، مہنگی دوبارہ تعمیر سے بچاتا ہے۔ (3) Skia/Impeller انجن — دوبارہ پینٹ کی حدوں کے ذریعے کم سے کم ڈرا کالز کے ساتھ C++ سطح پر رینڈرنگ۔

خلاصہ

  • Widget — Flutter میں UI کی ناقابل تبدیلی ترتیب، بنیادی تعمیراتی بلاک جو ظاہری شکل اور رویے کو بیان کرتا ہے۔
  • تین درخت — Flutter بہترین رینڈرنگ کے لیے Widget درخت (ترتیب)، Element درخت (رابطہ)، RenderObject درخت (رینڈرنگ) استعمال کرتا ہے۔
  • Stateless بمقابلہ Stateful — StatelessWidget بغیر حالت کے، StatefulWidget قابل تبدیل State اور UI اپ ڈیٹ کے لیے setState() طریقہ کے ساتھ۔
  • کمپوزیشن — UI وراثت کے بغیر child/children کے ذریعے Widgets نیسٹ کرکے بنایا جاتا ہے، لچک اور دوبارہ استعمال کی صلاحیت فراہم کرتا ہے۔
  • BuildContext — Theme، Navigator، MediaQuery اور InheritedWidget تک رسائی کے لیے درخت میں Widget پوزیشن کا وصف کنندہ۔
  • کارکردگی — Widgets ہر build پر دوبارہ بنائے جاتے ہیں (60 FPS)، لیکن RenderObject قسم کے مماثل ہونے پر دوبارہ استعمال ہوتا ہے۔
  • زمرے — Widgets کو layout (Row, Column, Stack)، painting (Container, Padding)، interactive (GestureDetector, TextField) اور platform (MaterialApp, Theme) میں تقسیم کیا گیا ہے۔

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں