How can i increase the number of ticks, a controller goes through, in a staggered animation (Flutter)

537

TickerProvider provides Ticker which simply means it tells our app that the device has updated the (or screen is updated), so that our AnimationController can generate a new value and we can redraw our widget according to that.

Generally speaking you can't really decide how many times the TickerProvider provides the Ticker. It entirely depends on the device and how many times it can refresh it's screen.

As Flutter Docs States :

Flutter aims to provide 60 frames per second (fps) performance, or 120 fps performance on devices capable of 120Hz updates. For 60fps, frames need to render approximately every 16ms. Jank occurs when the UI doesn't render smoothly.

In your case you're running your app on iOS Simulator and possibly in debug mode. Please don't check your app's performance either in debug mode or on a simulator. Use a real device and run you app in release or profile mode to check the real performance of a flutter app.

Launch the app in profile mode as follows:

In Android Studio and IntelliJ, use the Run > Flutter Run main.dart in Profile Mode menu item. In VS Code, open your launch.json file, and set the flutterMode property to profile (when done profiling, change it back to release or debug):

"configurations": [
  {
    "name": "Flutter",
    "request": "launch",
    "type": "dart",
    "flutterMode": "profile"
  }
]

From the command line, use the --profile flag:

$ flutter run --profile

Please visit official flutter docs for more info on performance :

Share:
537
Jerbs
Author by

Jerbs

Updated on December 27, 2022

Comments

  • Jerbs
    Jerbs over 1 year

    i created my staggered animation following the official tutorial : https://flutter.dev/docs/development/ui/animations/staggered-animations.

    The issue is that the number of ticks the controller goes thought (and thus the frame rate) is low, about 50 fps (it can be even lower in some other exemples i tried). Is there a way to increase the number of ticks an (animation)Controller goes through, or is there a better solution for this ? Thanks !

    Here's a gif of the laggy widget: https://i.stack.imgur.com/aXdef.gif ==> (StackOverflow does not want me to put images yet, so you got a link instead)

    I printed each frame/tick, here's what i got:

    flutter: 100.0 -> frame 0
    flutter: 100.0 -> frame 1
    flutter: 100.32715344429016 -> frame 2
    flutter: 100.72060895198956 -> frame 3
    ...
    flutter: 199.6830144248088 -> frame 40
    flutter: 200.0 -> frame 41
    flutter: 200.0 -> frame 42
    flutter: 200.0 -> frame 43
    flutter: 200.0 -> frame 44
    flutter: 200.0 -> frame 45
    flutter: 200.0 -> frame 46
    

    Here is my full code:

    class VerificationBox extends StatefulWidget {
      @override
      _VerificationBoxState createState() => _VerificationBoxState();
    }
    
    class _VerificationBoxState extends State<VerificationBox>
        with TickerProviderStateMixin {
      bool _isOpened = false;
      AnimationController _controller;
    
      @override
      void initState() {
        super.initState();
        _controller = AnimationController(
            duration: const Duration(milliseconds: 1000), vsync: this);
      }
    
      Future<void> _playAnimation() async {
        try {
          _isOpened
              ? await _controller.reverse().orCancel
              : await _controller.forward().orCancel;
        } on TickerCanceled {
          // the animation got canceled, probably because it was disposed of
        }
      }
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () {
            _playAnimation();
            _isOpened = !_isOpened;
          },
          child: StaggerAnimation(controller: _controller.view),
        );
      }
    }
    
    class StaggerAnimation extends StatelessWidget {
      StaggerAnimation({Key key, this.controller}):
            opacity = Tween<double>(
              begin: 0.0,
              end: 1.0,
            ).animate(
              CurvedAnimation(
                parent: controller,
                curve: Interval(
                  0.9,
                  1,
                  curve: Curves.linear,
                ),
              ),
            ),
            width = Tween<double>(
              begin: 100.0,
              end: 200.0,
            ).animate(
              CurvedAnimation(
                parent: controller,
                curve: Interval(
                  0.0,
                  0.9,
                  curve: Curves.easeInOutCirc,
                ),
              ),
            ),
            super(key: key);
    
      final AnimationController controller;
      final Animation<double> opacity;
      final Animation<double> width;
      int counter = 0;
    
      Widget _buildAnimation(BuildContext context, Widget child) {
        print('${width.value} -> frame $counter');
        counter++;
        return Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(35),
                  color: Colors.green,
                ),
                // curve: Curves.easeInOut,
                height: 25,
                width: width.value,
                // duration: Duration(milliseconds: 500),
                child: Row(
                  children: [
                    Container(
                      alignment: Alignment.center,
                      width: 80,
                      height: 50,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(35),
                        color: Colors.red[300],
                      ),
                      child: Text(
                        'verification',
                        style: TextStyle(fontSize: 13),
                        textAlign: TextAlign.center,
                      ),
                    ),
                    Expanded(
                      child: Opacity(
                        opacity: opacity.value,
                        child: Text(
                          'BCDEFG',
                          textAlign: TextAlign.center,
                        ),
                      ),
                    )
                  ],
                ));
      }
    
      @override
      Widget build(BuildContext context) {
        return AnimatedBuilder(
          builder: _buildAnimation,
          animation: controller,
        );
      }
    }
    
    • Shubhamhackz
      Shubhamhackz about 3 years
      You're running the app on a physical device ?
    • Jerbs
      Jerbs about 3 years
      No, on the iOS simulator, and in debug mode. I just realized that the animation is perfect on a pushed page (62 fps), so there is an issue with my bottom-app-bar pages (every animations seem laggy on them). I gotta fix that, but i'm still interested in the answer for this question
  • Jerbs
    Jerbs about 3 years
    That's the answer ! Thanks for your help <3