Flutter Widgets — Google Flutter ফ্রেমওয়ার্কের ইউজার ইন্টারফেসের মৌলিক বিল্ডিং ব্লক, যা ডিসেম্বর ২০১৮ সালে স্থিতিশীল সংস্করণ ১.০ এ প্রকাশিত হয়েছিল। Flutter-এ, সবকিছুই একটি উইজেট: স্ক্রিন এবং বাটন থেকে শুরু করে প্যাডিং এবং অ্যালাইনমেন্ট পর্যন্ত। উইজেটগুলি একটি ট্রি (widget tree) গঠন করে, যা Flutter তার নিজস্ব Skia/Impeller ইঞ্জিনে রেন্ডার করে, প্ল্যাটফর্মের নেটিভ কম্পোনেন্টগুলি এড়িয়ে। Google I/O (২০২৫) অনুযায়ী, Google Play এবং App Store-এ ৫০০,০০০-এর বেশি অ্যাপে Flutter ব্যবহার করা হয়। Flutter আর্কিটেকচার উইজেটগুলিকে StatelessWidget (অপরিবর্তনীয়) এবং StatefulWidget (State অবজেক্টের মাধ্যমে পরিবর্তনযোগ্য অবস্থাসহ) এ বিভক্ত করে।
মূল পয়েন্ট
Flutter Widgets — Flutter ফ্রেমওয়ার্কের সব UI এলিমেন্ট, অপরিবর্তনীয় (immutable) Dart ক্লাস হিসেবে বাস্তবায়িত। একটি উইজেট হলো একটি UI এলিমেন্টের কনফিগারেশন: এর আকার, রং, অবস্থান এবং ইভেন্ট হ্যান্ডলার। Android (XML + View) বা iOS (Storyboard + UIView)-এর বিপরীতে, Flutter নেটিভ কম্পোনেন্ট ব্যবহার করে না — সবকিছু Canvas-এ Skia (Android/iOS/Linux) বা Impeller (iOS/macOS) ইঞ্জিন দ্বারা আঁকা হয়। এটি প্ল্যাটফর্মের পার্থক্য ছাড়াই সব প্ল্যাটফর্মে সামঞ্জস্যপূর্ণ চেহারা নিশ্চিত করে। Flutter উইজেটের দুটি সেট নিয়ে আসে: Material Widgets (Android/ওয়েবের জন্য Google Material Design 3) এবং Cupertino Widgets (iOS/macOS-এর জন্য Apple HIG)। ডেভেলপার একটি অ্যাপ্লিকেশনে উভয় সেট একত্রিত করতে পারেন। প্রতিটি উইজেটের একটি build() মেথড থাকে যা একটি চাইল্ড উইজেট বা তাদের সংমিশ্রণ রিটার্ন করে — এভাবেই উইজেট ট্রি তৈরি হয়।
Flutter তিনটি ট্রি নিয়ে কাজ করে: Widget Tree (কনফিগারেশন, ডেভেলপার দ্বারা তৈরি), Element Tree (ট্রিতে উইজেটের অবস্থানের ম্যাপিং, ফ্রেমওয়ার্ক দ্বারা পরিচালিত) এবং Render Tree (অবজেক্ট যা লেআউট গণনা করে এবং পেইন্টিং সম্পাদন করে)। একটি Widget একটি Element তৈরি করে, যা একটি RenderObject তৈরি করে। কনফিগারেশন পরিবর্তনের (rebuild) সময় Element পুনরায় ব্যবহার করা হয় — এটি Flutter-এর অপটিমাইজেশন মেকানিজম: যদি উইজেটের ধরন এবং key মিলে যায়, তাহলে Element পুনরায় তৈরি না করে নতুন কনফিগারেশন দিয়ে আপডেট করা হয়। তিনটি ট্রি বোঝা Flutter অ্যাপ্লিকেশনের কর্মক্ষমতা অপটিমাইজ করার চাবিকাঠি।
StatelessWidget — একটি উইজেট যা অভ্যন্তরীণ অবস্থা সংরক্ষণ করে না। এটি কনস্ট্রাক্টরের মাধ্যমে প্যারামিটার গ্রহণ করে এবং build-এর পরে পরিবর্তনের সম্ভাবনা ছাড়াই সেগুলি প্রদর্শন করে। StatelessWidget স্থির উপাদানের জন্য আদর্শ: শিরোনাম, আইকন, অবতার, নির্দিষ্ট ডেটা সহ তালিকা। build() মেথড তৈরি করার সময় একটি বার এবং যখন প্যারেন্ট উইজেট পরিবর্তিত হয় তখন কল করা হয়। যেহেতু StatelessWidget-এর কোনো অবস্থা নেই, এটির আলাদা State অবজেক্টের প্রয়োজন নেই — build() সরাসরি উইজেট ক্লাসে সংজ্ঞায়িত করা হয়।
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-কে প্যারেন্ট রিবিল্ডের সময় উইজেট ইনস্ট্যান্স পুনরায় ব্যবহার করতে দেয় — সব StatelessWidget-এর জন্য প্রস্তাবিত একটি মাইক্রো-অপটিমাইজেশন।
StatefulWidget — একটি পৃথক State অবজেক্টে সংরক্ষিত পরিবর্তনযোগ্য অবস্থাসহ উইজেট। StatefulWidget নিজেই অপরিবর্তনীয়, StatelessWidget-এর মতো। পরিবর্তনযোগ্য অংশটি State-কে অর্পণ করা হয়েছে: State একটি অবজেক্ট যা একবার তৈরি হয় এবং একাধিক উইজেট রিবিল্ড থেকে রক্ষা পায়। যখন অবস্থা পরিবর্তিত হয় (setState()), Flutter State-এ build() কল করে, UI আপডেট করে। StatefulWidget ইন্টারঅ্যাকটিভ এলিমেন্টের জন্য ব্যবহৃত হয়: কাউন্টার, টেক্সট ফিল্ড, চেকবক্স, অ্যানিমেশন, টাইমার।
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 — State ক্লাস _LikeButtonState সহ একটি StatefulWidget। ফিল্ড liked এবং count State-এ সংরক্ষিত অবস্থা এবং রিবিল্ডে রিসেট হয় না। setState() Flutter-কে জানায় যে UI পুনর্নির্মাণের প্রয়োজন। Flutter প্রতিটি প্যারেন্ট রিবিল্ডে State পুনরায় তৈরি করে না — শুধুমাত্র যখন কনফিগারেশন (key বা উইজেট টাইপ) পরিবর্তিত হয়। IT Sectr-এ, আমরা প্রদর্শনের জন্য StatelessWidget এবং ইন্টারঅ্যাকটিভ কম্পোনেন্টের জন্য StatefulWidget ব্যবহার করি, মিউটেশনের সীমানা পর্যন্ত StatefulWidget কমানোর নীতি অনুসরণ করে।
Widget Tree — অ্যাপ্লিকেশন UI বর্ণনাকারী উইজেটের শ্রেণিবদ্ধ কাঠামো। Flutter Widget Tree-কে Element Tree-তে রূপান্তর করে: প্রতিটি Widget একটি Element তৈরি করে, যা ট্রিতে তার অবস্থান এবং RenderObject-এর সাথে সংযোগ ট্র্যাক করে। Render Tree লেআউট (আকার এবং অবস্থান নির্ধারণ) এবং পেইন্ট (রেন্ডারিং) সম্পাদন করে। Element একটি গুরুত্বপূর্ণ অপটিমাইজেশন স্তর: যদি রিবিল্ডের সময় উইজেট টাইপ এবং key পরিবর্তিত না হয়, তাহলে Element পুনরায় ব্যবহার করা হয়, RenderObject পুনরায় তৈরি না করে কনফিগারেশন আপডেট করে। এটি উচ্চ ফ্রেম রেটে (60/120 FPS) Flutter-এর কর্মক্ষমতা নিশ্চিত করে।
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 উইজেট')),
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 মূল Material Design লেআউট উইজেট। Center তার চাইল্ড Column-কে কেন্দ্রীভূত করে। Column চিল্ড্রেনকে কেন্দ্র অ্যালাইনমেন্ট (mainAxisAlignment.center) সহ vertically সাজায়। Flutter লেআউট উপরে থেকে নীচে (প্যারেন্ট থেকে constraints পাঠানো হয়) এবং আকার নীচে থেকে উপরে (sizedByParent বা চিল্ড্রেন থেকে সাইজিং) গণনা করে।
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”-এর মতো ত্রুটির কারণ হয়। কনটেক্সট সংরক্ষণ করার পরিবর্তে, ডেটা অ্যাক্সেসের জন্য Builder উইজেট বা InheritedWidget প্যাটার্ন ব্যবহার করুন।
Key — প্রতিটি উইজেটের কনস্ট্রাক্টরের একটি ঐচ্ছিক প্যারামিটার (super.key)। Key Flutter-কে তালিকায় আইটেমের ক্রম বা সংখ্যা পরিবর্তনের সময় উইজেট সনাক্ত করতে সাহায্য করে। Key ছাড়া, Flutter টাইপ এবং অবস্থান দ্বারা উইজেট তুলনা করে; Key ছাড়া তালিকার মাঝখানে একটি আইটেম যোগ করলে, Flutter ভুল উইজেটের জন্য Element পুনরায় ব্যবহার করে, যার ফলে স্টেট বাগ (StatefulWidget) এবং অ্যানিমেশন সমস্যা হয়। তালিকার জন্য ValueKey (ইউনিক আইডেন্টিফায়ার), ObjectKey (ডেটা অবজেক্টের উপর ভিত্তি করে), UniqueKey (প্রতি রিবিল্ডে গ্যারান্টিড ইউনিক — জোর করে পুনর্নির্মাণের জন্য) ব্যবহার করুন।
Flutter SDK (স্থিতিশীল সংস্করণ 3.3+, Dart 3+) ২০০+ বিল্ট-ইন উইজেট অন্তর্ভুক্ত করে বিভাগে বিভক্ত: 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)। লেআউট উইজেট যেকোনো Flutter UI-এর ভিত্তি: Row অনুভূমিক অনুক্রমের জন্য, Column উল্লম্বের জন্য, Stack ওভারল্যাপিং এলিমেন্টের জন্য, সাজসজ্জার জন্য BoxDecoration সহ Container।
| বিভাগ | মূল উইজেট | উদ্দেশ্য |
|---|---|---|
| Layout | Row, Column, Stack, Container, Expanded, Flexible | চাইল্ড এলিমেন্টের অবস্থান এবং আকার নির্ধারণ |
| Material | Scaffold, AppBar, Card, Drawer, FAB, TabBar | Material Design 3 UI কম্পোনেন্ট |
| Cupertino | CupertinoPageScaffold, CupertinoNavigationBar, CupertinoButton | iOS-স্টাইলের কম্পোনেন্ট |
| Painting | Opacity, ClipRect, Transform, DecoratedBox, BackdropFilter | ভিজ্যুয়াল ইফেক্ট এবং ক্লিপিং |
| Async | FutureBuilder, StreamBuilder | UI অবস্থাসহ অ্যাসিনক্রোনাস ডেটা লোডিং |
| Accessibility | Semantics, MergeSemantics | স্ক্রিন রিডারের জন্য সিম্যান্টিক মার্কআপ |
প্রায়শই জিজ্ঞাসিত প্রশ্ন
StatelessWidget-এর কোনো অভ্যন্তরীণ অবস্থা নেই — সব ডেটা কনস্ট্রাক্টরের মাধ্যমে পাঠানো হয় এবং পরিবর্তিত হয় না। StatefulWidget একটি পৃথক State অবজেক্টে পরিবর্তনযোগ্য অবস্থা সংরক্ষণ করে যা রিবিল্ড থেকে রক্ষা পায়। অবস্থা পরিবর্তন করলে setState() কল হয়, এবং Flutter UI পুনর্নির্মাণ করে। অপরিবর্তনীয় এলিমেন্টের জন্য StatelessWidget ব্যবহার করুন; ইন্টারঅ্যাকটিভ এলিমেন্টের জন্য StatefulWidget ব্যবহার করুন।
BuildContext Element Tree-তে উইজেটের অবস্থানের একটি বর্ণনাকারী, build() মেথডে পাঠানো হয়। কনটেক্সটের মাধ্যমে, উইজেট MediaQuery, Theme, Navigator, ScaffoldMessenger এবং InheritedWidget-এ অ্যাক্সেস পায়। BuildContext build() শেষ হওয়ার পরে সংরক্ষণ করা উচিত নয়। ডেটা অ্যাক্সেসের জন্য, Builder উইজেট বা InheritedWidget ব্যবহার করুন।
হ্যাঁ, Flutter Dart-কে তার একমাত্র প্রোগ্রামিং ভাষা হিসেবে ব্যবহার করে। Dart একটি স্ট্যাটিক টাইপযুক্ত ভাষা যার null safety, sound null safety, extension methods এবং pattern matching রয়েছে। শুরু করার জন্য, Dart-এর মৌলিক বিষয় যথেষ্ট: ক্লাস, ফাংশন, async/await, সংগ্রহ। Dart Dart Native-এর মাধ্যমে নেটিভ কোড (AOT) এবং Dart2JS-এর মাধ্যমে JavaScript (ওয়েবের জন্য) কম্পাইল হয়।
না, Flutter ছয়টি প্ল্যাটফর্ম সমর্থন করে: iOS, Android, Web, macOS, Windows, Linux। ৯০% এর বেশি কোড সব প্ল্যাটফর্মে শেয়ার করা হয়। প্ল্যাটফর্ম অ্যাডাপ্টেশন (ক্যামেরা, ফাইল সিস্টেম) প্লাগইন বা প্ল্যাটফর্ম চ্যানেলের মাধ্যমে বাস্তবায়িত হয়। ডেস্কটপের জন্য, Flutter Flutter Desktop উইন্ডো শেল ব্যবহার করে; ওয়েবের জন্য, এটি CanvasKit (WebGL) বা HTML রেন্ডারার ব্যবহার করে।
Flutter 60/120 FPS অর্জন করে: নিজস্ব 2D ইঞ্জিন (Skia/Impeller), নেটিভ ব্রিজের অনুপস্থিতি (React Native-এর বিপরীতে), তিনটি ট্রি (Widget → Element → Render) টাইপ/key অপরিবর্তিত থাকলে Element পুনর্ব্যবহার, এক-দিকনির্দেশক পাস সহ লেআউট অ্যালগরিদম (constraints নীচে, sizes উপরে) এবং স্ক্রিনের পৃথক এলাকার পুনরায় পেইন্টিং আলাদা করার জন্য RepaintBoundary।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন