تكرار السؤال: …
الإجابة المختصرة
يقوم AnimatedBuilder بإعادة رسم وبناء الويدجت الفرعي المتحرك فقط في كل فريم، مع إمكانية تمرير الشجرة الثابتة كـ child جاهز يتم تفاديه تماماً من الـ Rebuild.
الشرح
استدعاء addListener(() => setState(...)) على AnimationController يؤدي لإعادة استدعاء دالة build() للويدجت بالكامل 60 أو 120 مرة في الثانية، مما يهدر الـ CPU ويسبب سقوط الفريمات (Jank). في المقابل، يستمع AnimatedBuilder للـ Listenable مباشرة ويقتصر الـ rebuild على محتواه الداخلي فقط، وعند تمرير الـ child المعقد، لا يتم استدعاء بناء هذا الـ child نهائياً، بل يُعاد استخدامه في طبقة العرض مباشرة.
مثال بالكود
AnimatedBuilder(
animation: _controller,
child: const HeavyComplexChildWidget(), // يتم بناؤه مرة واحدة فقط!
builder: (context, child) {
return Transform.scale(
scale: _animation.value,
child: child, // يعاد استخدامه دون إعادة بنائه
);
},
)أخطاء شائعة
- بناء الويدجت الثابت داخل دالة builder الخاصة بـ AnimatedBuilder بدلاً من تمريره عبر معامل child، مما يهدر ميزة الأداء بالكامل.