Flutter - Animation رفرفة - رسوم متحركة أنيميشين فلاطر

 Flutter - Animation رفرفة - رسوم متحركة أنيميشين فلاطر

Flutter - Animation رفرفة - رسوم متحركة أنيميشين فلاطر


Flutter - Animation رفرفة - رسوم متحركة أنيميشين فلاطر

 هناك العديد من الطرق التي تجعل Flutter من السهل إنشاء الرسوم المتحركة ، من Tweens الأساسية إلى الرسوم المتحركة الضمنية المضمنة في إطار العمل. وإذا كانت هذه لا تناسب احتياجاتك ، فهناك حلول طرف ثالث تفعل أي شيء تقريبًا يمكنك تخيله. من التدوير إلى التلاشي ، وتحولات الحجم وحتى الرسوم المتحركة حيث تنتقل أداة واحدة من صفحة إلى أخرى ، يجعل Flutter الأمر سهلاً!

لكن السهولة قد تكون في بعض الأحيان سهلة للغاية. لا تخطئ في اتخاذ قرار بشأن النهج الأسهل ، دون عناء النظر في كيفية عمله. بعض الأشياء أغلى من غيرها ، وإذا كنت تستخدم واحدًا من هذه الأشياء في كل مكان عندما يعمل شيء أبسط أيضًا ، فيمكنك حينئذٍ سحب أداء تطبيقك إلى الزحف.

هذا اختصار يقوموا بتدريسه بالفعل في بعض من أفضل كليات الهندسة في الولايات المتحدة. مخيف أليس كذلك؟

الشيء الذي يمكن أن يكون مثالًا على محاولة قتل نملة بمطرقة ثقيلة هو الإفراط في استخدام AnimatedContainer. قد يكون من المغري جدًا استخدامه في أي وقت تحتاج فيه إلى تحريك حاوية أو جعلها تبدو وكأن أطفالها يقومون بالرسوم المتحركة ، حيث يمكنها فعل أي شيء. ولكن ما يجب أن تكون على دراية به هو أنه في وقت التشغيل سيحاول تحريك كل ما في وسعه ، وليس فقط الأشياء التي تغيرت. لا يمكنك رؤيته لأن قيم بداية ونهاية الرسوم المتحركة هي نفسها ، حيث لم يتغير شيء. لكنها تخلق Tweens لتحريك تلك الخصائص التي لم تتغير ، فقط نفس الشيء.

لذلك ، إذا كنت ستقوم فقط بتحريك معلمة واحدة فقط ، فقد ترغب في معرفة ما إذا كان يمكنك استخدام عنصر واجهة مستخدم يقوم فقط بتحريك هذه المعلمة المحددة. إذا كنت تريد تغيير حجم شيء ما ، فيمكنك استخدام AnimatedSize Widget. تريد تحريك الحشو ، التعتيم ، المحاذاة؟ نعم ، هناك عنصر واجهة مستخدم لذلك.

فيما يلي بعض الأشياء التي يقوم بها AnimatedContainer وكيف يمكنك إنجاز نفس الأشياء باستخدام عناصر واجهة مستخدم متحركة أخرى.

كما ترون ، هناك القليل. إذا قرأت المستندات بعناية ، فسترى أن كل خاصية تحدد قيمة لها سيتم تحريكها في كل مرة يتغير فيها أي شيء:

هناك ثلاثة أشياء رئيسية يجب النظر إليها هنا:

  1. ستتحرك الحاوية بين القيم القديمة والجديدة عندما يتغير شيء ما.
  2. الخصائص غير الفارغة ليست متحركة.
  3. انها child  و فروع ليست متحركة.

لاحظ أنه لا يوجد شيء يقال هنا حول ما إذا كانت القيم القديمة والجديدة متساوية. إذا قمت بتعيين قيم الطول والعرض واللون ، فعندما تقوم بتحريك الارتفاع ، سيظل العرض واللون محسوبًا.

هل هذا مروع؟ في الواقع لا. إنه حقا ليس بذلك السوء. قد يبدو أنك تستخدم مطرقة لقتل نملة ، لكن من ناحية الأداء ، لا يختلف الأمر بشكل رهيب عن هذا:

نأمل أن توضح المسافة البيضاء المضافة ما يحدث هنا. وفقًا للمستندات ، سيتم تحريك AnimatedSize كلما تغير حجم الطفل الصغير ... ولكن التجربة أظهرت أنه لا يزال يعمل على الرغم من أن الحاوية هي حفيد AnimatedSize ، وليس الطفل المباشر.

هذا صحيح ، يؤدي تغيير _opacity أو _ height أو _width إلى تشغيل الرسوم المتحركة المناسبة ، على الرغم من أن _الارتفاع والعرض _ موجودان في حفيد AnimatedSize.

هذا يعني أنك يمكن، وهذا هو يمكن ، عش القطعة المتحركة ضمنيا لكل الخاصية التي تريد الأرواح، دون استخدام AnimatedContainer التي من شأنها تحريك كل الممتلكات قمت بتعيين ما إذا كنت تغييره أم لا. في هذه الحالة ، كان من الممكن أن يتضمن ذلك اللون الأزرق ، على الرغم من أنه لم يتغير أبدًا.

لكن مرة أخرى ، هل هذا حل أكثر فاعلية؟ حسنًا ، ليس حقًا. الشيء الرئيسي الذي أنجزته هو جعلك تفكر حقًا في كل هذه الأشياء ؛ هكذا تتعلم.

إلى جانب ذلك ، كانت أفضل طريقة يمكن أن أفكر بها لإدخال "DnKAWaSh" هنا.

الحقيقة هي ، إذا كنت تستخدم AnimatedContainer ، فسيكون لديك Tween محسوب لكل خاصية ، ولكن هناك متحكم AnimationController واحد فقط لكل منهم. إذا كنت تستخدم عناصر واجهة مستخدم منفصلة ومتداخلة ، فسيكون لديك متحكم AnimationController مختلف لكل منها ، ولكن يتم تشغيل كل عنصر فقط إذا تغيرت خصائصه المحددة. ومع ذلك ، مع Widgets منفصلة ، فإن حقيقة وجود AnimationController الإضافي يعني أن لديك الآن شريطًا إضافيًا وعنصرًا إضافيًا لكل عنصر واجهة مستخدم إضافي تستخدمه سواء قمت بتشغيله أم لا ... لذلك هناك أداء ناجح إذا ذهبت بهذه الطريقة أيضًا.

في النهاية ، ترجع مسألة الأداء إلى هذا: إذا كنت تريد حقًا تعديل الأداء ، فلا يجب عليك استخدام الرسوم المتحركة الضمنية على أي حال. يجب أن تشمر عن سواعدك ، وتقوم ببعض الأعمال المخصصة ، وتضبطها مثل سيارة السباق.

ولكن إذا كنت ترغب في القيام بذلك ، فلن تقرأ مقالًا عن الرسوم المتحركة للأشخاص الكسالى ، أليس كذلك؟ بالطبع لا! دعنا نعود إلى بعض الأشياء التي يمكننا القيام بها في وضع EZ ، أليس كذلك؟

إذن ما هي بعض الأدوات المصغّرة المتحركة ضمنيًا التي يمكننا استخدامها؟

  • Animated Size حجم الصورة المتحركة
  • Animated Opacity الشاففية
  • AnimatedPadding الحشو
  • AnimatedPositioned (استخدام محدود. فقط عندما تكون القيود فضفاضة ، مثل المكدس)
  • AmimatedWidget (يتحرك بين أنواع مختلفة من الأدوات ، مثل نص وأيقونة)
  • Hero (تحريك عنصر واجهة مستخدم من صفحة إلى أخرى ، عندما يظهر في كلتا الصفحتين)

ودعونا لا ننسى AnimatedContainer!

المزيد من الرسوم المتحركة المعقدة ، الطريق السهل

تحتاج أحيانًا إلى شيء أكثر تعقيدًا ، لكنك لا تريد إنشاءه يدويًا. هذا هو المكان الذي يأتي فيه Rive. ربما سمعت عنهم بأسماء مختلفة ، 2Dimensions و Flare. 2Dimensions هو الاسم القديم للشركة وكان Flare هو الاسم القديم للمحرر نفسه. اليوم ، كلاهما يعرف باسم Rive.

يتكون Rive من المحرر ، الذي يمكنه استيراد ملفات SVG و Lottie ، ورمز وقت تشغيل Rive. تعمل مجتمعة على وضع الرسوم المتحركة المخصصة في تطبيقك.

يمكن أن تكون الرسوم المتحركة تفاعلية ، لإنشاء جميع أنواع التأثيرات التي تتفاعل مع مدخلات وإجراءات المستخدم. أي: الدب تيدي ، في جلسة Flutter Interact على Rive ، اجعل عينيه تتبعان المؤشر أثناء كتابة اسم المستخدم الخاص بك. كما يعرض أيضًا رسمًا متحركًا سعيدًا إذا قمت بتقديم كلمة المرور الصحيحة وكلمة المرور غير سعيدة إذا قمت بتقديم كلمة مرور خاطئة. يمكن مزج الرسوم المتحركة مع بعضها البعض ، مما يؤدي إلى انتقالات سلسة بدلاً من الظهور فجأة من رسم متحرك إلى آخر.

يمكن وضع المكونات في طبقات وتحريكها بشكل فردي ، وكذلك التلاعب بالعظام التي تستخدم علم الحركة ؛ يشبه إلى حد كبير Unity و Blender 3D وغيرها من برامج إنشاء الألعاب / الرسوم المتحركة.

بالإضافة إلى ذلك ، مثل Unity و Blender ، فإن الرسوم المتحركة والمنصات مستقلة عن المكونات الرسومية التي تتعامل معها ، مما يسمح بإعادة استخدام المنصات والرسوم المتحركة مرارًا وتكرارًا بواسطة شخصيات وكائنات رسومية مختلفة. هذا يعني أنه يمكنك إنشاء رسم متحرك مرة واحدة وإعادة استخدامه مرارًا وتكرارًا.

يمكنك معرفة الأحدث (اعتبارًا من ديسمبر 2019) من خلال مشاهدة جلستهم من 


يقصد  بالرسوم المتحركة Animation هي بالحركات التفاعلية مع الأدوات والصورة مثل ظهور واختفاء شريط عنوان  زر صورة ظهور قائمة منسدلة تحرك الصور الي اخره

الرسوم المتحركة Animation هي إجراء معقد في أي تطبيق جوال. على الرغم من تعقيدها ، تعمل الرسوم المتحركة Animation على تحسين تجربة المستخدم إلى مستوى جديد وتوفر تفاعلًا ثريًا للمستخدم. نظرًا لثرائها ، تصبح الرسوم المتحركة Animationجزءًا لا يتجزأ من تطبيقات الهاتف المحمول الحديثة. يدرك إطار عمل Flutter أهمية الرسوم المتحركة ويوفر إطارًا بسيطًا وبديهيًا لتطوير جميع أنواع الرسوم المتحركة Animation.

المقدمة

الرسوم المتحركة Animation هي عملية عرض سلسلة من الصور / الصور بترتيب معين خلال مدة محددة لإعطاء وهم بالحركة. أهم جوانب الرسوم المتحركة هي كما يلي -

  • الرسوم المتحركة Animation لها قيمتان مميزتان: قيمة البداية وقيمة النهاية. يبدأ الرسم المتحرك من قيمة البداية ويمر عبر سلسلة من القيم الوسيطة وينتهي في النهاية عند قيم النهاية. على سبيل المثال ، لتحريك عنصر واجهة مستخدم حتى يتلاشى ، ستكون القيمة الأولية هي التعتيم الكامل والقيمة النهائية ستكون التعتيم الصفري.

  • قد تكون القيم الوسيطة خطية أو غير خطية (منحنى) بطبيعتها ويمكن تهيئتها. افهم أن الرسوم المتحركة تعمل كما تم تكوينها. يوفر كل تكوين طابعًا مختلفًا للرسوم المتحركة. على سبيل المثال ، سيكون تلاشي عنصر واجهة مستخدم خطيًا بطبيعته بينما ارتداد الكرة سيكون غير خطي بطبيعته.

  • تؤثر مدة عملية الرسوم المتحركة Animation على سرعة (بطء أو ثبات) الرسوم المتحركة  Animation.

  • القدرة على التحكم في عملية الرسوم المتحركة Animation مثل بدء الرسوم المتحركة Animation ، وإيقاف الرسوم المتحركة ، وتكرار الرسوم المتحركة Animation لتعيين عدد المرات ، وعكس عملية الرسوم المتحركة ، وما إلى ذلك ،

  • في Flutter ، لا يقوم نظام الرسوم المتحركة Animation بأي حركة حقيقية. بدلاً من ذلك ، يوفر فقط القيم المطلوبة في كل إطار لعرض الصور.

دروس الرسوم المتحركة Animation flutter 

يعتمد نظام الرسوم المتحركة Flutter على كائنات الرسوم المتحركة. فئات الرسوم المتحركة Animation flutter 

 الأساسية واستخدامها هي كما يلي -

الرسوم المتحركة Animation flutter 

يولد قيمًا محرفة بين رقمين خلال مدة معينة. أكثر فئات الرسوم المتحركة  Animation flutter شيوعًا هي -

  • <Animation<double> الرسوم المتحركة <مزدوج> - اختر القيم بين رقمين عشريين

  • <Animation<Color> الرسوم المتحركة <اللون> - اختر الألوان بين لونين

  • <Animation<Size> الرسوم المتحركة <الحجم> - اختر الأحجام بين حجمين

  • AnimationController - كائن الرسوم المتحركة الخاص للتحكم في الرسوم المتحركة نفسها. يولد قيمًا جديدة عندما يكون التطبيق جاهزًا لإطار جديد. وهو يدعم الرسوم المتحركة المستندة إلى الخطي وتبدأ القيمة من 0.0 إلى 1.0

controller = AnimationController(duration: const Duration(seconds: 2), vsync: this);

هنا ، تتحكم وحدة التحكم في الرسوم المتحركة وخيار المدة يتحكم في مدة عملية الرسوم المتحركة. vsync هو خيار خاص يستخدم لتحسين الموارد المستخدمة في الرسوم المتحركة Flutter - Animation   .

منحنية

يشبه AnimationController ولكنه يدعم الرسوم المتحركة غير الخطية. يمكن استخدام CurvedAnimation مع كائن الرسوم المتحركةFlutter - Animation   على النحو التالي -

controller = AnimationController(duration: const Duration(seconds: 2), vsync: this); 
animation = CurvedAnimation(parent: controller, curve: Curves.easeIn)

توين  <T> 

مشتق من Animatable <T> ويستخدم لتوليد أرقام بين أي رقمين بخلاف 0 و 1. ويمكن استخدامه مع كائن الرسوم المتحركة باستخدام طريقة الحركة وتمرير كائن الرسوم المتحركة الفعلي.

AnimationController controller = AnimationController( 
   duration: const Duration(milliseconds: 1000), 
vsync: this); Animation<int> customTween = IntTween(
   begin: 0, end: 255).animate(controller);
  • يمكن أيضًا استخدام Tween مع CurvedAnimation على النحو التالي -

  • AnimationController controller = AnimationController(
       duration: const Duration(milliseconds: 500), vsync: this); 
    final Animation curve = CurvedAnimation(parent: controller, curve: Curves.easeOut); 
    Animation<int> customTween = IntTween(begin: 0, end: 255).animate(curve);

هنا ، وحدة التحكم هي وحدة تحكم الرسوم المتحركة Flutter - Animation  الفعلية. يوفر المنحنى نوع غير الخطي ويوفر customTween نطاقًا مخصصًا من 0 إلى 255.

تدفق العمل للرسوم المتحركة Flutter

سير عمل الرسوم المتحركةFlutter - Animation  كالتالي -

  • حدد وحدة تحكم الرسوم المتحركة Flutter - Animation  وابدأها في الحالة المبدئية لـ State fulWidget.

  • AnimationController(duration: const Duration(seconds: 2), vsync: this); 
    animation = Tween<double>(begin: 0, end: 300).animate(controller); 
    controller.forward();
  • أضف مستمعًا قائمًا على الرسوم المتحركة ، وأضف مستمعًا لتغيير حالة القطعة.


  • animation = Tween<double>(begin: 0, end: 300).animate(controller) ..addListener(() {
       setState(() { 
          // The state that has changed here is the animation object’s value. 
       }); 
    });
  • يمكن استخدام عناصر واجهة المستخدم المضمنة و AnimatedWidget و AnimatedBuilder لتخطي هذه العملية. يقبل كل من عنصر واجهة المستخدم كائن الرسوم المتحركة ويحصل على القيم الحالية المطلوبة للرسوم المتحركة.

  • احصل على قيم الرسوم المتحركة أثناء عملية إنشاء الأداة ثم قم بتطبيقها على العرض أو الارتفاع أو أي خاصية ذات صلة بدلاً من القيمة الأصلية.

  • child: Container( 
       height: animation.value, 
       width: animation.value, 
       child: <Widget>, 
    )

تطبيق flutter animation 

دعونا نكتب تطبيقًا بسيطًا يعتمد على الرسوم المتحركة لفهم مفهوم الرسوم المتحركة في إطار عمل Flutter.

  • قم بإنشاء تطبيق Flutter جديد في Android studio ، product_animation_app.

  • انسخ مجلد الأصول من product_nav_app إلى product_animation_app وأضف الأصول داخل ملف pubspec.yaml.


  • flutter: 
       assets: 
       - assets/appimages/floppy.png 
       - assets/appimages/iphone.png 
       - assets/appimages/laptop.png 
       - assets/appimages/pendrive.png 
       - assets/appimages/pixel.png 
       - assets/appimages/tablet.png
  • قم بإزالة رمز بدء التشغيل الافتراضي (main.dart).

  • إضافة الاستيراد والوظيفة الأساسية الأساسية.

  • import 'package:flutter/material.dart'; 
    void main() => runApp(MyApp());
  • قم بإنشاء عنصر واجهة مستخدم MyApp مشتق من StatefulWidgtet.

  • class MyApp extends StatefulWidget { 
       _MyAppState createState() => _MyAppState(); 
    }
  • إنشاء عنصر واجهة مستخدم _MyAppState وتنفيذ initState والتخلص منها بالإضافة إلى طريقة الإنشاء الافتراضية.

  • class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { 
       Animation<double> animation; 
       AnimationController controller; 
       @override void initState() {
          super.initState(); 
          controller = AnimationController(
             duration: const Duration(seconds: 10), vsync: this
          ); 
          animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller); 
          controller.forward(); 
       } 
       // This widget is the root of your application. 
       @override 
       Widget build(BuildContext context) {
          controller.forward(); 
          return MaterialApp(
             title: 'Flutter Demo',
             theme: ThemeData(primarySwatch: Colors.blue,), 
             home: MyHomePage(title: 'Product layout demo home page', animation: animation,)
          ); 
       } 
       @override 
       void dispose() {
          controller.dispose();
          super.dispose();
       }
    }

هنا،

  • في طريقة initState ، أنشأنا كائن تحكم للرسوم المتحركة Flutter - Animation (وحدة تحكم) ، وكائن متحرك (رسوم متحركة) وبدأنا الرسوم المتحركة باستخدام controller.forward.

  • في طريقة التخلص ، تخلصنا من كائن وحدة التحكم في الرسوم المتحركة (وحدة التحكم).

  • في طريقة البناء ، أرسل الرسوم المتحركةFlutter - Animation  إلى أداة MyHomePage من خلال المُنشئ. الآن ، يمكن لعنصر واجهة مستخدم MyHomePage استخدام كائن الرسوم المتحركةFlutter - Animation  لتحريك محتواه.

  • الآن ، أضف أداة ProductBox


  • class ProductBox extends StatelessWidget {
       ProductBox({Key key, this.name, this.description, this.price, this.image})
          : super(key: key);
       final String name; 
       final String description; 
       final int price; 
       final String image; 
       
       Widget build(BuildContext context) {
          return Container(
             padding: EdgeInsets.all(2), 
             height: 140, 
             child: Card( 
                child: Row( 
                   mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                   children: <Widget>[ 
                      Image.asset("assets/appimages/" + image), 
                      Expanded( 
                         child: Container( 
                            padding: EdgeInsets.all(5), 
                            child: Column( 
                               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                               children: <Widget>[ 
                                  Text(this.name, style: 
                                     TextStyle(fontWeight: FontWeight.bold)), 
                                  Text(this.description), 
                                     Text("Price: " + this.price.toString()), 
                               ], 
                            )
                         )
                      )
                   ]
                )
             )
          ); 
       }
    }
  • قم بإنشاء عنصر واجهة مستخدم جديد ، MyAnimatedWidget لعمل رسوم متحركة تتلاشى بسيطة باستخدام التعتيم.

  • class MyAnimatedWidget extends StatelessWidget { 
       MyAnimatedWidget({this.child, this.animation}); 
          
       final Widget child; 
       final Animation<double> animation; 
       
       Widget build(BuildContext context) => Center( 
       child: AnimatedBuilder(
          animation: animation, 
          builder: (context, child) => Container( 
             child: Opacity(opacity: animation.value, child: child), 
          ), 
          child: child), 
       ); 
    }
  • هنا ، استخدمنا AniatedBuilder لعمل الرسوم المتحركة Flutter - Animation  الخاصة بنا. AnimatedBuilder هي أداة تقوم ببناء محتواها أثناء عمل الرسوم المتحركة في نفس الوقت. يقبل كائن الرسوم المتحركةFlutter - Animation  للحصول على قيمة الرسوم المتحركة Flutter - Animation  الحالية. لقد استخدمنا قيمة الرسوم المتحركة ، animation.value لتعيين تعتيم عنصر واجهة المستخدم الفرعي. في الواقع ، ستعمل الأداة على تحريك عنصر واجهة المستخدم الفرعي باستخدام مفهوم العتامة.

  • أخيرًا ، قم بإنشاء عنصر واجهة مستخدم MyHomePage واستخدم كائن الرسوم المتحركةFlutter - Animation  لتحريك أي من محتوياته.

  • class MyHomePage extends StatelessWidget {
       MyHomePage({Key key, this.title, this.animation}) : super(key: key); 
       
       final String title; 
       final Animation<double> 
       animation; 
       
       @override 
       Widget build(BuildContext context) {
          return Scaffold(
             appBar: AppBar(title: Text("Product Listing")),body: ListView(
                shrinkWrap: true,
                padding: const EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0), 
                children: <Widget>[
                   FadeTransition(
                      child: ProductBox(
                         name: "iPhone", 
                         description: "iPhone is the stylist phone ever", 
                         price: 1000, 
                         image: "iphone.png"
                      ), opacity: animation
                   ), 
                   MyAnimatedWidget(child: ProductBox(
                      name: "Pixel", 
                      description: "Pixel is the most featureful phone ever", 
                      price: 800, 
                      image: "pixel.png"
                   ), animation: animation), 
                   ProductBox(
                      name: "Laptop", 
                      description: "Laptop is most productive development tool", 
                      price: 2000, 
                      image: "laptop.png"
                   ), 
                   ProductBox(
                      name: "Tablet", 
                      description: "Tablet is the most useful device ever for meeting", 
                      price: 1500, 
                      image: "tablet.png"
                   ), 
                   ProductBox(
                      name: "Pendrive", 
                      description: "Pendrive is useful storage medium", 
                      price: 100, 
                      image: "pendrive.png"
                   ),
                   ProductBox(
                      name: "Floppy Drive", 
                      description: "Floppy drive is useful rescue storage medium", 
                      price: 20, 
                      image: "floppy.png"
                   ),
                ],
             )
          );
       }
    }

هنا ، استخدمنا FadeAnimation و MyAnimationWidget لتحريك أول عنصرين في القائمة. FadeAnimation هي فئة رسوم متحركةFlutter - Animation  مدمجة ، استخدمناها لتحريك طفلها باستخدام مفهوم العتامة.

  • الكود الكامل كما يلي -

  • import 'package:flutter/material.dart'; 
    void main() => runApp(MyApp()); 
    
    class MyApp extends StatefulWidget { 
       _MyAppState createState() => _MyAppState(); 
    } 
    class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
       Animation<double> animation; 
       AnimationController controller; 
       
       @override 
       void initState() {
          super.initState(); 
          controller = AnimationController(
             duration: const Duration(seconds: 10), vsync: this); 
          animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller); 
          controller.forward(); 
       } 
       // This widget is the root of your application. 
       @override 
       Widget build(BuildContext context) {
          controller.forward(); 
          return MaterialApp( 
             title: 'Flutter Demo', theme: ThemeData(primarySwatch: Colors.blue,), 
             home: MyHomePage(title: 'Product layout demo home page', animation: animation,) 
          ); 
       } 
       @override 
       void dispose() {
          controller.dispose();
          super.dispose(); 
       } 
    }
    class MyHomePage extends StatelessWidget { 
       MyHomePage({Key key, this.title, this.animation}): super(key: key);
       final String title; 
       final Animation<double> animation; 
       
       @override 
       Widget build(BuildContext context) {
          return Scaffold(
             appBar: AppBar(title: Text("Product Listing")), 
             body: ListView(
                shrinkWrap: true, 
                padding: const EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0), 
                children: <Widget>[
                   FadeTransition(
                      child: ProductBox(
                         name: "iPhone", 
                         description: "iPhone is the stylist phone ever", 
                         price: 1000, 
                         image: "iphone.png"
                      ), 
                      opacity: animation
                   ), 
                   MyAnimatedWidget(
                      child: ProductBox( 
                         name: "Pixel", 
                         description: "Pixel is the most featureful phone ever", 
                         price: 800, 
                         image: "pixel.png"
                      ), 
                      animation: animation
                   ), 
                   ProductBox( 
                      name: "Laptop", 
                      description: "Laptop is most productive development tool", 
                      price: 2000, 
                      image: "laptop.png"
                   ), 
                   ProductBox(
                      name: "Tablet",
                      description: "Tablet is the most useful device ever for meeting",
                      price: 1500, 
                      image: "tablet.png"
                   ), 
                   ProductBox(
                      name: "Pendrive", 
                      description: "Pendrive is useful storage medium", 
                      price: 100, 
                      image: "pendrive.png"
                   ), 
                   ProductBox(
                      name: "Floppy Drive", 
                      description: "Floppy drive is useful rescue storage medium", 
                      price: 20, 
                      image: "floppy.png"
                   ), 
                ], 
             )
          ); 
       } 
    } 
    class ProductBox extends StatelessWidget { 
       ProductBox({Key key, this.name, this.description, this.price, this.image}) :
          super(key: key);
       final String name; 
       final String description; 
       final int price; 
       final String image; 
       Widget build(BuildContext context) {
          return Container(
             padding: EdgeInsets.all(2), 
             height: 140, 
             child: Card(
                child: Row(
                   mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                   children: <Widget>[ 
                      Image.asset("assets/appimages/" + image), 
                      Expanded(
                         child: Container( 
                            padding: EdgeInsets.all(5), 
                            child: Column( 
                               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                               children: <Widget>[ 
                                  Text(
                                     this.name, style: TextStyle(
                                        fontWeight: FontWeight.bold
                                     )
                                  ), 
                                  Text(this.description), Text(
                                     "Price: " + this.price.toString()
                                  ), 
                               ], 
                            )
                         )
                      ) 
                   ]
                )
             )
          ); 
       } 
    }
    class MyAnimatedWidget extends StatelessWidget { 
       MyAnimatedWidget({this.child, this.animation}); 
       final Widget child; 
       final Animation<double> animation; 
     
       Widget build(BuildContext context) => Center( 
          child: AnimatedBuilder(
             animation: animation, 
             builder: (context, child) => Container( 
                child: Opacity(opacity: animation.value, child: child), 
             ), 
             child: child
          ), 
       ); 
    }
  • قم بتجميع التطبيق وتشغيله لمعرفة النتائج. النسخة الأولية والنهائية للتطبيق كالتالي -

Flutter - Animation رفرفة - رسوم متحركة أنيميشين فلاطر

Flutter - Animation رفرفة - رسوم متحركة أنيميشين فلاطر