Flutter نے ڈیولپرز کو ایک ہی کوڈ بیس سے موبائل، ویب اور ڈیسک ٹاپ کے لیے خوبصورت، مقامی طور پر مرتب کردہ ایپلیکیشنز بنانے کے قابل بنا کر موبائل ڈویلپمنٹ لینڈ سکیپ کو تبدیل کر دیا ہے۔ اپنی بھرپور ویجیٹ لائبریری، تاثراتی UI فریم ورک، اور افسانوی ہاٹ ری لوڈ فیچر کے ساتھ، Flutter ٹیموں کو تیز رفتاری سے اعادہ کرنے اور ریکارڈ وقت میں پالش یوزر انٹرفیس فراہم کرنے کی طاقت دیتا ہے۔
اس جامع گائیڈ میں، ہم ان بنیادی تصورات کو تلاش کریں گے جو Flutter کو تیز رفتار موبائل UI کی ترقی کے لیے ایک غیر معمولی انتخاب بناتے ہیں، ویجیٹ ٹری کو سمجھنے سے لے کر پیچیدہ اینیمیشنز اور ریسپانسیو لے آؤٹس کو نافذ کرنے تک۔
Flutter ویجیٹ ٹری کو سمجھنا
Flutter میں ہر چیز ایک ویجیٹ ہے۔ پوری ایپلیکیشن ویجٹ کے درخت کے طور پر بنائی گئی ہے، جہاں ہر ویجیٹ صارف کے انٹرفیس کے ایک حصے کو بیان کرتا ہے۔ اس اعلانیہ نقطہ نظر کا مطلب ہے کہ آپ بیان کرتے ہیں کہ کسی دی گئی ریاست کے لیے UI کیسا نظر آنا چاہیے، اور Flutter ریاست کے تبدیل ہونے پر رینڈرنگ کو اپ ڈیٹ کرنے کا خیال رکھتا ہے۔
MaterialAppیاCupertinoAppبیٹھتا ہے، جو تھیمنگ اور نیویگیشن اسکافولڈنگ فراہم کرتا ہے۔ اس کے نیچے، آپ چھوٹے، دوبارہ قابل استعمال ویجیٹس سے اپنا UI تحریر کرتے ہیں۔ اس درجہ بندی کو سمجھنا موثر Flutter ایپلیکیشنز بنانے کے لیے بنیادی ہے۔import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Flutter App',
theme: ThemeData(
colorSchemeSeed: Colors.blue,
useMaterial3: true,
),
home: const HomeScreen(),
);
}
}درخت میں ہر ویجیٹ میں ایک متعلقہElementہے جو درخت میں اس کی پوزیشن کی نمائندگی کرتا ہے اور ایکRenderObjectجو ترتیب اور پینٹنگ کو سنبھالتا ہے۔ Flutter کی رینڈرنگ پائپ لائن کم سے کم اپ ڈیٹس کا تعین کرنے کے لیے ویجیٹ کے درخت کو مؤثر طریقے سے مختلف کرتی ہے، یہاں تک کہ آپ کے UI کی کارکردگی کو بار بار دوبارہ بنانے کے باوجود بھی برقرار رکھا جاتا ہے۔
سٹیٹ لیس بمقابلہ سٹیٹ فل ویجیٹس
Flutter ویجیٹ کی دو بنیادی اقسام فراہم کرتا ہے جو آپ کے ایپلیکیشن آرکیٹیکچر میں مختلف مقاصد کو پورا کرتا ہے۔
اسٹیٹ لیس ویجیٹ
AStatelessWidgetناقابل تغیر ہے۔ ایک بار بننے کے بعد، یہ اپنی اندرونی حالت کو تبدیل نہیں کر سکتا۔ یہ وجیٹس UI عناصر کے لیے مثالی ہیں جو مکمل طور پر ان کو دی گئی ترتیب اور درخت میں ان کے اوپر وراثت میں ملنے والے ویجٹس پر منحصر ہیں۔ وہ ہلکے ہیں، جانچنے میں آسان ہیں، اور آپ کا ڈیفالٹ انتخاب ہونا چاہیے۔
class UserCard extends StatelessWidget {
final String name;
final String email;
final String avatarUrl;
const UserCard({
super.key,
required this.name,
required this.email,
required this.avatarUrl,
});
@override
Widget build(BuildContext context) {
return Card(
elevation: 2,
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(avatarUrl),
),
title: Text(name),
subtitle: Text(email),
trailing: const Icon(Icons.arrow_forward_ios),
),
);
}
}StatefulWidget
AStatefulWidgetتغیر پذیر حالت کو برقرار رکھتا ہے جو ویجیٹ کی زندگی بھر میں تبدیل ہو سکتی ہے۔ جب حالتsetState()کے ذریعے تبدیل ہوتی ہے، Flutter نئی حالت کی عکاسی کرنے کے لیے ویجیٹ کو دوبارہ بناتا ہے۔ انٹرایکٹو عناصر جیسے فارم، ٹوگلز، اور اینیمیٹڈ اجزاء کے لیے اسٹیٹفول ویجیٹس استعمال کریں۔
class CounterWidget extends StatefulWidget {
const CounterWidget({super.key});
@override
State<CounterWidget> createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _count = 0;
void _increment() {
setState(() {
_count++;
});
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Count: $_count', style: Theme.of(context).textTheme.headlineMedium),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _increment,
child: const Text('Increment'),
),
],
);
}
}لے آؤٹ سسٹم: قطار، کالم، اسٹیک، اور فلیکس
Flutter کا لے آؤٹ سسٹم فلیکس پر مبنی ویجیٹس کے ایک طاقتور سیٹ پر بنایا گیا ہے جو آپ کو اس بات پر قطعی کنٹرول فراہم کرتا ہے کہ عناصر کو اسکرین پر کیسے ترتیب دیا جاتا ہے۔
قطار اور کالم
Rowبچوں کو افقی طور پر ترتیب دیتا ہے، جبکہColumnانہیں عمودی ترتیب دیتا ہے۔ دونوں مرکزی محور اور کراس ایکسس کے ساتھ سیدھ میں معاونت کرتے ہیں، اورExpandedاورFlexibleویجیٹس استعمال کرنے والے بچوں میں جگہ تقسیم کر سکتے ہیں۔
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 2,
child: Text('Title', style: Theme.of(context).textTheme.titleLarge),
),
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {},
child: const Text('Action'),
),
),
],
)Stack
Stackآپ کو ویجیٹس کو ایک دوسرے کے اوپر چڑھانے کی اجازت دیتا ہے۔ یہ پیچیدہ بصری کمپوزیشن بنانے کے لیے انمول ہے جیسے امیج اوورلیز، بیجز، اور فلوٹنگ ایکشن عناصر۔ بچوں کو اسٹیک کے اندر مخصوص مقامات پر رکھنے کے لیےPositionedاستعمال کریں۔
Stack(
children: [
Image.asset('assets/background.jpg', fit: BoxFit.cover),
Positioned(
bottom: 16,
left: 16,
right: 16,
child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.black54,
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'Overlay Text',
style: TextStyle(color: Colors.white, fontSize: 18),
),
),
),
],
)لچکدار لے آؤٹ پیٹرنز
Expanded،Flexible، اورSpacerکو یکجا کریں تاکہ جدید ترین لے آؤٹس بنائیں جو دستیاب جگہ کے مطابق ہوں۔Expandedبچے کو باقی جگہ بھرنے پر مجبور کرتا ہے، جبکہFlexibleبچے کو اس کے مختص کردہ فلیکس فیکٹر سے چھوٹا ہونے کی اجازت دیتا ہے۔
Responsive Design with MediaQuery اور LayoutBuilder
بلڈنگ ریسپانسیو UIs جو فونز، ٹیبلیٹ اور یہاں تک کہ ڈیسک ٹاپ پر کام کرتے ہیں Flutter کے ریسپانسیو ڈیزائن ٹولز کو سمجھنے کی ضرورت ہے۔
MediaQueryموجودہ ڈیوائس کے بارے میں معلومات فراہم کرتا ہے، بشمول اسکرین کا سائز، واقفیت، پکسل کثافت، اور سسٹم کی ترجیحات۔ دستیاب جگہ کی بنیاد پر ترتیب کے فیصلے کرنے کے لیے اسے استعمال کریں۔
class ResponsiveLayout extends StatelessWidget {
const ResponsiveLayout({super.key});
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
final isTablet = screenWidth > 600;
final isDesktop = screenWidth > 1200;
return Scaffold(
body: isDesktop
? Row(
children: [
const NavigationRail(destinations: []),
Expanded(child: _buildContent(crossAxisCount: 4)),
],
)
: _buildContent(crossAxisCount: isTablet ? 3 : 2),
);
}
Widget _buildContent({required int crossAxisCount}) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAxisCount,
crossAxisSpacing: 16,
mainAxisSpacing: 16,
),
itemCount: 20,
itemBuilder: (context, index) => Card(
child: Center(child: Text('Item $index')),
),
);
}
}LayoutBuilderایک اور طاقتور ٹول ہے جو پیرنٹ ویجیٹ کی رکاوٹوں کو فراہم کرتا ہے، جس سے آپ کو فل سکرین کے طول و عرض کی بجائے اصل دستیاب جگہ کی بنیاد پر مختلف لے آؤٹ بنانے کی اجازت ملتی ہے۔ یہ خاص طور پر دوبارہ قابل استعمال اجزاء کے لیے مفید ہے جنہیں اپنے کنٹینر کے مطابق ڈھالنے کی ضرورت ہے۔
تھیمنگ اور میٹریل ڈیزائن 3
Flutter کا تھیمنگ سسٹم آپ کو اپنی پوری ایپلیکیشن میں ایک مستقل بصری زبان کی وضاحت کرنے دیتا ہے۔ میٹریل ڈیزائن 3 کے ساتھ، آپ ایک بیج کے رنگ سے مکمل رنگ سکیم بنا سکتے ہیں۔
MaterialApp(
theme: ThemeData(
colorSchemeSeed: const Color(0xFF1A73E8),
useMaterial3: true,
textTheme: const TextTheme(
headlineLarge: TextStyle(fontWeight: FontWeight.bold),
bodyLarge: TextStyle(fontSize: 16, height: 1.5),
),
cardTheme: CardTheme(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: BorderSide(color: Colors.grey.shade200),
),
),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
filled: true,
),
),
)Theme.of(context)کا استعمال کرتے ہوئے اپنے ویجیٹ ٹری میں کہیں بھی تھیم کی خصوصیات تک رسائی حاصل کریں۔ یہ بصری مستقل مزاجی کو یقینی بناتا ہے اور آپ کےMaterialAppکو ایک متبادلdarkThemeفراہم کرکے ڈارک موڈ کو نافذ کرنا معمولی بنا دیتا ہے۔
اینیمیشنز اور ٹرانزیشنز
Flutter ہموار، پرفارمنس اینیمیشنز پر سبقت لے جاتا ہے۔ فریم ورک مختلف پیچیدگی کی سطحوں کے مطابق ہونے کے لیے مضمر اور واضح حرکت پذیری APIs فراہم کرتا ہے۔
امپلیسیٹ اینیمیشنز
پراپرٹی کی سادہ تبدیلیوں کے لیے، پرانی اور نئی اقدار کے درمیان مضمر اینیمیشنز خود بخود متحرک ہو جاتی ہیں۔AnimatedContainer،AnimatedOpacity، اورAnimatedPaddingجیسے وجیٹس کو کم سے کم کوڈ کی ضرورت ہوتی ہے۔
AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
width: _isExpanded ? 300 : 150,
height: _isExpanded ? 200 : 100,
decoration: BoxDecoration(
color: _isExpanded ? Colors.blue : Colors.green,
borderRadius: BorderRadius.circular(_isExpanded ? 16 : 8),
),
child: const Center(child: Text('Tap me')),
)واضح اینیمیشنز
مزید کنٹرول کے لیے،Tweenاشیاء کے ساتھAnimationControllerاستعمال کریں۔ یہ آپ کو وقت، ترتیب، اور حرکت پذیری کے منحنی خطوط پر عمدہ کنٹرول فراہم کرتا ہے۔
class PulseAnimation extends StatefulWidget {
const PulseAnimation({super.key});
@override
State<PulseAnimation> createState() => _PulseAnimationState();
}
class _PulseAnimationState extends State<PulseAnimation>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _scaleAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 1),
vsync: this,
)..repeat(reverse: true);
_scaleAnimation = Tween<double>(begin: 0.95, end: 1.05).animate(
CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ScaleTransition(
scale: _scaleAnimation,
child: const FlutterLogo(size: 100),
);
}
}صفحہ ٹرانزیشنز
مخصوص اسکرین ٹرانزیشنز بنانے کے لیےPageRouteBuilderکا استعمال کرتے ہوئے نیویگیشن ٹرانزیشنز کو حسب ضرورت بنائیں جو آپ کی ایپ کی شخصیت کو نکھارتے ہیں۔
ہاٹ ری لوڈ ورک فلو
Flutter کا ہاٹ ری لوڈ ترقی کی رفتار کے لیے گیم چینجر ہے۔ جب آپ کسی فائل کو محفوظ کرتے ہیں، تو Flutter اپ ڈیٹ شدہ سورس کوڈ کو چلتے ہوئے Dart VM میں داخل کرتا ہے، جو آپ کی ایپ کی موجودہ حالت کو محفوظ رکھتا ہے۔ اس کا مطلب ہے کہ آپ ویجیٹ کی پیڈنگ کو موافقت دے سکتے ہیں، رنگ تبدیل کر سکتے ہیں، یا کسی ترتیب کو دوبارہ ترتیب دے سکتے ہیں اور ایک سیکنڈ کے اندر نتائج دیکھ سکتے ہیں۔
ہاٹ ری لوڈ کی تاثیر کو زیادہ سے زیادہ کرنے کے لیے، ان بہترین طریقوں پر عمل کریں: X
constکے بطور نشان زد کریں۔ اس سے Flutter کی شناخت میں مدد ملتی ہے کہ درخت کے کن حصوں کو دوبارہ تعمیر کرنے کی ضرورت ہے اور کارکردگی کو بہتر بناتا ہے۔Flutter UI
کے لیے کارکردگی کے نکات تیز رفتار UIs بنانے کے لیے کئی اہم شعبوں پر توجہ دینے کی ضرورت ہے:
1۔ const Widgets کا استعمال کریں
کو XPR239X
وجیٹس کو XPR239X
کے طور پر اعلان کرنے کی اجازت دیں مکمل طور پر تعمیر نو کو چھوڑ دیں۔ یہ سب سے آسان اور سب سے زیادہ مؤثر اصلاح میں سے ایک ہے۔
2. دوبارہ تعمیر کا دائرہ کم سے کم کریں
setState()استعمال کرتے وقت، صرف کالنگ ویجیٹ اور اس کی اولاد دوبارہ تعمیر کرتے ہیں۔ ریاستی تبدیلیوں کے دھماکے کے رداس کو محدود کرنے کے لیے اپنے ریاستی وجیٹس کو چھوٹا اور مرکوز رکھیں۔
3. لمبی فہرستوں کے لیے ListView.builder کا استعمال کریں
کبھی بھیListViewبڑے ڈیٹا سیٹس کے لیے بچوں کی جامد فہرست کے ساتھ استعمال نہ کریں۔ اس کے بجائے،ListView.builderکا استعمال کریں جو آئٹمز کو سستی سے بناتا ہے جب وہ منظر میں سکرول کرتے ہیں، ڈرامائی طور پر میموری کے استعمال کو کم کرتے ہیں۔
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(items[index].title),
subtitle: Text(items[index].description),
);
},
)4. کیش مہنگی کمپیوٹیشنز
RepaintBoundaryویجیٹ استعمال کریں تاکہ UI کے اکثر تبدیل ہونے والے حصوں کو جامد حصوں سے الگ کریں۔ یہ مستحکم مواد کی غیر ضروری دوبارہ پینٹ کو روکتا ہے۔
5۔ امیجز کو بہتر بنائیں
مناسب سائز کی تصاویر استعمال کریں اور نیٹ ورک امیجز کے لیےcached_network_imageاستعمال کرنے پر غور کریں۔Imageویجیٹس پرcacheWidthاورcacheHeightکی وضاحت کریں تاکہ تصاویر کو ان کے مکمل ریزولوشن کے بجائے ڈسپلے کے سائز پر ڈی کوڈ کریں۔
ایک مکمل UI مثال بنانا
آئیے ہم ہر چیز کو ایک عملی مثال کے ساتھ لاتے ہیں جو ترتیب، تھیمنگ، اور تعامل کو یکجا کرتی ہے۔
class ProductCard extends StatelessWidget {
final String title;
final String price;
final String imageUrl;
final VoidCallback onAddToCart;
const ProductCard({
super.key,
required this.title,
required this.price,
required this.imageUrl,
required this.onAddToCart,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Card(
clipBehavior: Clip.antiAlias,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AspectRatio(
aspectRatio: 16 / 9,
child: Image.network(imageUrl, fit: BoxFit.cover),
),
Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: theme.textTheme.titleMedium),
const SizedBox(height: 4),
Text(price, style: theme.textTheme.titleLarge?.copyWith(
color: theme.colorScheme.primary,
fontWeight: FontWeight.bold,
)),
const SizedBox(height: 8),
SizedBox(
width: double.infinity,
child: FilledButton.icon(
onPressed: onAddToCart,
icon: const Icon(Icons.shopping_cart),
label: const Text('Add to Cart'),
),
),
],
),
),
],
),
);
}
}نتیجہ
Flutter موبائل UIs بنانے کے لیے ایک ناقابل یقین حد تک نتیجہ خیز ماحول فراہم کرتا ہے۔ اس کا ویجیٹ پر مبنی فن تعمیر، ہاٹ ری لوڈ، ایک بھرپور تھیمنگ سسٹم، اور طاقتور لے آؤٹ پرائمیٹوز کے ساتھ مل کر، ڈویلپرز کو پہلے سے کہیں زیادہ تیزی سے خوبصورت، ریسپانسیو ایپلی کیشنز بنانے کے قابل بناتا ہے۔ ویجیٹ ٹری کو سمجھ کر، ویجیٹ کی صحیح اقسام کا انتخاب کرکے، ترتیب کے نظام کا فائدہ اٹھا کر، اور کارکردگی کے بہترین طریقوں پر عمل کرتے ہوئے، آپ ایسے UIs بنا سکتے ہیں جو نہ صرف بصری طور پر شاندار ہوں بلکہ کارکردگی اور دیکھ بھال کے قابل بھی ہوں۔
چاہے آپ ایک سادہ پروٹو ٹائپ بنا رہے ہوں یا ایک پیچیدہ پروڈکشن ایپلیکیشن، Flutter کی UI ٹول کٹ آپ کی ضروریات کے مطابق ہے۔ سادہ کمپوزیشن کے ساتھ شروع کریں، وسیع ویجیٹ کیٹلاگ کا فائدہ اٹھائیں، اور آپ کی ایپلیکیشن بڑھنے کے ساتھ ساتھ بتدریج مزید جدید نمونوں کو اپنایں۔ ہاٹ ری لوڈ اور Flutter کے ایکسپریسو API کے ذریعے تیزی سے تکرار کا امتزاج موبائل UI ڈیولپمنٹ کو حقیقی طور پر خوشگوار تجربہ بناتا ہے۔