Flutter Things

About Flutter Render Widget (Widget Tree, Element Tree, Render Object Tree)
Widget Tree: যার সাথে আমারা সবাই পরিচিত In Flutter EveryThing Is Widget.এই Widget Tree হলো হায়ারার্কিক্যাল ইজার ইন্টারফেস এর রিপ্রেসেনটেশন ও ব্লু-প্রিন্ট। যেখানে প্রতিটি Widget এর বিভিন্ন ধরনের propertice থাকে। সহজ কথায় যদি বলতে হয় তাহলে এই ভাবে বলার যায় যে আমারা Flutter দিয়ে অ্যাপ বানানোর পর যে UI দেখা যায় এই ui দেখানোর জন্য Flutter Widget নামে অনেকগুলি function আছে এইগুলি ব্যবহার করতে হয়. আর ওই Widget কিন্তু immutable এবং যখন অ্যাপ এ state আপডেট হয় তখন Widget নতুন ভালুএ নিয়ে আবার rebuilt হয়।
let’s see in Flutter source code:
abstract class StatelessWidget extends Widget {}
abstract class StatefulWidget extends Widget {}
আমরা সব সময় StatelessWidget and StatefulWidget ব্যবহার করি আর এই গুলি Widget class থেকে Inherit করে
@immutable
abstract class Widget extends DiagnosticableTree {}
আবার, Flutter-এ Widget ক্লাসটি কিন্তু immutable। এখন প্রশ্ন হচ্ছে — যেহেতু Widget immutable, তাহলে state আপডেট হলে কীভাবে UI রিবিল্ড হয়?
মূলত, যখন আমরা setState() কল করি এরপর markNeedsBuild() মেথডকে কল করে। এই মেথডটি Element-কে রি-বিল্ড করার জন্য শিডিউল করে ফেলে।
পরবর্তী বিল্ড ফেজে, Flutter ফ্রেমওয়ার্ক সেই Element এর build() মেথড পুনরায় কল করে, যার মাধ্যমে নতুন widget tree তৈরি হয়। এরপর পুরাতন ও নতুন widget tree-এর মধ্যে তুলনা করে UI-তে আপডেট করে।
void setState(VoidCallback fn) {
//
_element!.markNeedsBuild();
}
void markNeedsBuild() {
owner!.scheduleBuildFor(this);
}
Element Tree: আমরা উপড়ে যে widget tree নিয়ে দেখলাম এই widget কিন্তু tree এর কোন জায়গা থাকে তার কাছে কোণ ইনফর্মেশন থাকে না। এর জন্য Flutter এ আরেক ধরনের ম্যকানিজম আছে যাকে বলা হয় Element। এই Element হচ্ছে widget এর প্রেরেন্ট,চিলড্রেন,সাইজ,ট্রি এর মধ্যে Widget এর পজিশন, renderObject ইত্যাদি ইনফর্মেশন গুলা রাখে. Element কিন্তু mutable
let’s see in flutter source code:
@immutable
abstract class Widget extends DiagnosticableTree {
/// Initializes [key] for subclasses.
const Widget({ this.key });
@protected
@factory
Element createElement();
যখন আমরা কোন widget কে তৈরি করি তখন সে createElement কে function কে কল করে এবং এই function Element object কে রির্টান করে
abstract class Element extends DiagnosticableTree implements BuildContext {}
এবং এখানে Element ক্লাস হচ্ছে BuildContext কে implement করছে। এখানে BuildContext এর সাথে সবায় পরিচিত যেটা StatelessWidget ক্লাস এর build(*BuildContext context*) function এর পারামিটার হিসাবে আসে। তার মানে Widget এর Element build function এর পারামিটার হিসাবে আসে যার মাধমে widget tree এর মধ্যে widget লোকেশন জানা যায়
আমরা যদি বিভিন্ন widget দেখি
abstract class StatelessWidget extends Widget {
/// Initializes [key] for subclasses.
const StatelessWidget({ super.key });
/// Creates a [StatelessElement] to manage this widget's location in the tree.
///
/// It is uncommon for subclasses to override this method.
@override
StatelessElement createElement() => StatelessElement(this);
class StatelessElement extends ComponentElement {
/// Creates an element that uses the given widget as its configuration.
StatelessElement(StatelessWidget super.widget);
এখানে StatelessWidget হচ্ছে সে StatelessElement তৈরি করতেছে এই Element ComponentElement extend করতেছে। যদি অন্য আরেকটা widget দেখি
class SizedBox extends SingleChildRenderObjectWidget {}
abstract class SingleChildRenderObjectWidget extends RenderObjectWidget {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const SingleChildRenderObjectWidget({ super.key, this.child });
/// The widget below this widget in the tree.
///
/// {@macro flutter.widgets.ProxyWidget.child}
final Widget? child;
@override
SingleChildRenderObjectElement createElement() => SingleChildRenderObjectElement(this);
}
class SingleChildRenderObjectElement extends RenderObjectElement {}
এই খানে SizedBox হচ্ছে SingleChildRenderObjectWidget কে extend করতেছে যেটা আলাদ ভিন্ন ধরনের এর element RenderObjectElement। ComponentElement হচ্ছে root element হিসাবে বিবেচিত হয়। যেটা সরাসরি RenderObject এর সাথে যুক্ত না কিন্তু এই ComponentElement ইন্ডিরেক্টলি RenderObject জেনেরেট করে.
অন্যদিকে RenderObjectElement হচ্ছে Element Tree এর মধ্যে actively লেআউট এবং painting phase rendering এর সাথে যুক্ত এবং এই RenderObjectElement হচ্ছে RenderObject এর সাথে যুক্ত আবার এই RenderObject হচ্ছে sizing, positioning, hit-testing, and painting অপারেশান করে থাকে UI render করার জন্য।
Render Object Tree:রেন্ডার অবজেক্ট ট্রি UI-এর লেআউট এবং রেন্ডারিংয়ের কাজ করে.এই ট্রি তে লেআউট calculation করে আর painting করে থাকে । এই ভাবে বলার যায় সাইজ,পজিশন,রেন্ডেরিং এর জন্য রেস্পন্সিবল। Render Object কিন্তু mutable