Easily add staggered animations to your ListView, GridView, Column and Row children.

Overview

Flutter Staggered Animations

Easily add staggered animations to your ListView, GridView, Column and Row children as shown in Material Design guidelines

Showcase

ListView GridView Column

Flutter 2.0 and null-safety

From 1.0.0 and onwards, flutter_staggered_animations is null-safe and requires Dart SDK 2.12.0 minimum. If you want to keep using flutter_staggered_animations but cannot migrate to null-safety yet, use the version 0.1.3 instead.

Installation

Dependency

Add the package as a dependency in your pubspec.yaml file.

dependencies:
  flutter_staggered_animations: "^1.0.0"

Import

Import the package in your code file.

import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';

Basic usage

Here is a sample code to apply a staggered animation on ListView items.

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: AnimationLimiter(
      child: ListView.builder(
        itemCount: 100,
        itemBuilder: (BuildContext context, int index) {
          return AnimationConfiguration.staggeredList(
            position: index,
            duration: const Duration(milliseconds: 375),
            child: SlideAnimation(
              verticalOffset: 50.0,
              child: FadeInAnimation(
                child: YourListChild(),
              ),
            ),
          );
        },
      ),
    ),
  );
}

API Overview

This package contains three type of classes:

  • Animation
  • AnimationConfiguration
  • AnimationLimiter

Animations

Animations are split into 4 classes:

  • FadeInAnimation
  • SlideAnimation
  • ScaleAnimation
  • FlipAnimation

Animations can be composed to produce advanced animations effects by wrapping them.

Example of a SlideAnimation combined with a FadeInAnimation:

child: SlideAnimation(
  verticalOffset: 50.0,
    child: FadeInAnimation(
      child: YourListChild(),
    ),
)

Animations must be direct children of AnimationConfiguration.

AnimationConfiguration

AnimationConfiguration is an InheritedWidget that shares its animation settings with its children (mainly duration and delay).

Named constructors

Depending on the scenario in which you will present your animations, you should use one of AnimationConfiguration's named constructors.

  • AnimationConfiguration.synchronized if you want to launch all children's animations at the same time.
  • AnimationConfiguration.staggeredList if you want to delay the animation of each child to produce a single-axis staggered animations (from top to bottom or from left to right).
  • AnimationConfiguration.staggeredGrid if you want to delay the animation of each child to produce a dual-axis staggered animations (from left to right and top to bottom).

If you're not in the context of a ListView or GridView, an utility static method is available to help you apply staggered animations to the children of a Row or Column:

  • AnimationConfiguration.toStaggeredList

You can override duration and delay in each child Animation if needed.

AnimationLimiter

In the context of a scrollable view, your children's animations are only built when the user scrolls and they appear on the screen. This create a situation where your animations will be run as you scroll through the content. If this is not a behaviour you want in your app, you can use AnimationLimiter.

AnimationLimiter is an InheritedWidget that prevents the children widgets to be animated if they don't appear in the first frame where AnimationLimiter is built.

To be effective, AnimationLimiter must be a direct parent of your scrollable list of widgets.

You can omit AnimationLimiter if your view is not scrollable.

Quick samples

ListView

Here is a sample code to apply a staggered animation on the children of a ListView.

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: AnimationLimiter(
      child: ListView.builder(
        itemCount: 100,
        itemBuilder: (BuildContext context, int index) {
          return AnimationConfiguration.staggeredList(
            position: index,
            duration: const Duration(milliseconds: 375),
            child: SlideAnimation(
              verticalOffset: 50.0,
              child: FadeInAnimation(
                child: YourListChild(),
              ),
            ),
          );
        },
      ),
    ),
  );
}

GridView

Here is a sample code to apply a staggered animation on the children of a GridView.

@override
Widget build(BuildContext context) {
  int columnCount = 3;

  return Scaffold(
    body: AnimationLimiter(
      child: GridView.count(
        crossAxisCount: columnCount,
        children: List.generate(
          100,
          (int index) {
            return AnimationConfiguration.staggeredGrid(
              position: index,
              duration: const Duration(milliseconds: 375),
              columnCount: columnCount,
              child: ScaleAnimation(
                child: FadeInAnimation(
                  child: YourListChild(),
                ),
              ),
            );
          },
        ),
      ),
    ),
  );
}

Column

Here is a sample code to apply a staggered animation on the children of a Column.

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: AnimationLimiter(
          child: Column(
            children: AnimationConfiguration.toStaggeredList(
              duration: const Duration(milliseconds: 375),
              childAnimationBuilder: (widget) => SlideAnimation(
                horizontalOffset: 50.0,
                child: FadeInAnimation(
                  child: widget,
                ),
              ),
              children: YourColumnChildren(),
            ),
          ),
        ),
      ),
    );
  }

License

Flutter Staggered Animations is released under the MIT License

About us

We are a french mobile design and development team.

Website : https://www.mobiten.com

Comments
  • WidgetsBinding warnings after upgrading to Flutter 3.0

    WidgetsBinding warnings after upgrading to Flutter 3.0

    After upgrading to latest Flutter release 3.0, some warnings started appearing in the console logs. Hopefully these are only warnings.

    : Warning: Operand of null-aware operation '!' has type 'WidgetsBinding' which excludes null.
    ../…/src/animation_limiter.dart:43
    - 'WidgetsBinding' is from 'package:flutter/src/widgets/binding.dart' ('../../flutter/packages/flutter/lib/src/widgets/binding.dart').
    package:flutter/…/widgets/binding.dart:1
        WidgetsBinding.instance!.addPostFrameCallback((Duration value) {
    

    The error is generated from line https://github.com/mobiten/flutter_staggered_animations/blob/780941c20a088d8314c2e5a141bd2215ea294738/lib/src/animation_limiter.dart#L43

    opened by UsamaKarim 23
  • The method 'ancestorWidgetOfExactType' isn't defined for the class 'BuildContext'.

    The method 'ancestorWidgetOfExactType' isn't defined for the class 'BuildContext'.

    ../../../../../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_staggered_animations-0.1.2/lib/src/animation_configuration.dart:161:20: Error: The method 'ancestorWidgetOfExactType' isn't defined for the class 'BuildContext'.

    • 'BuildContext' is from 'package:flutter/src/widgets/framework.dart' ('../../../../../flutter/packages/flutter/lib/src/widgets/framework.dart'). Try correcting the name to the name of an existing method, or defining a method named 'ancestorWidgetOfExactType'. return context.ancestorWidgetOfExactType(AnimationConfiguration) ^^^^^^^^^^^^^^^^^^^^^^^^^

    Seems to be deprecated on master.

    https://stackoverflow.com/questions/65657716/error-the-method-ancestorstateoftype-isnt-defined-for-the-class-buildcontex

    bug 
    opened by bastaware 12
  • Resolve build warning, since Flutter 3.0

    Resolve build warning, since Flutter 3.0

    Problem

    Since the release of Flutter 3.0 there is a warning during the build of an app, using this package.

    The Warning:

    : Warning: Operand of null-aware operation '!' has type 'WidgetsBinding' which excludes null.
    ../…/src/animation_limiter.dart:43
    - 'WidgetsBinding' is from 'package:flutter/src/widgets/binding.dart' ('../../../fvm/versions/stable/packages/flutter/lib/src/widgets/binding.dart').
    package:flutter/…/widgets/binding.dart:1
        WidgetsBinding.instance!.addPostFrameCallback((Duration value) {
    

    Fix:

    I removed "!" from the instance property, because since the Flutter 3.0 release the instance getter will not return null anymore. As you can see here: binding.dart#L304 The commit associated with this change is this one: ab89ce285f76a3fd3a9328ec863f5623cc5ac8bc

    Information

    This merge would eliminate the support for all Flutter versions < 3.0.

    opened by mfrischbutter 9
  • How to deal with Expanded ?

    How to deal with Expanded ?

    Hello,

    Awesome code ;-) Just a thing, I would like to animate a Column with Expanded widgets. But the ancestor is not anymore a Flex if I use your Widget.

    > Expanded widgets must be placed directly inside Flex widgets.
    > Expanded(no depth, flex: 1, dirty) has a Flex ancestor, but there are other widgets between them:
    > - Opacity(opacity: 1.0)
    > - Transform
    > These widgets cannot come between a Expanded and its Flex.
    > 
    

    Any tips to work with ?

    Thank you very much

    enhancement 
    opened by QuentinSc 9
  • Fixed Flutter 3.0 hint

    Fixed Flutter 3.0 hint

    Issue:

    : Warning: Operand of null-aware operation '!' has type 'WidgetsBinding' which excludes null.
    ../…/src/animation_limiter.dart:43
    - 'WidgetsBinding' is from 'package:flutter/src/widgets/binding.dart' ('../../../fvm/versions/stable/packages/flutter/lib/src/widgets/binding.dart').
    package:flutter/…/widgets/binding.dart:1
        WidgetsBinding.instance!.addPostFrameCallback((Duration value) {
    

    Solution:

    /// This allows a value of type T or T?
    /// to be treated as a value of type T?.
    ///
    /// We use this so that APIs that have become
    /// non-nullable can still be used with `!` and `?`
    /// to support older versions of the API as well.
    T? _ambiguate<T>(T? value) => value;
    
        _ambiguate(WidgetsBinding.instance)!.addPostFrameCallback((Duration value) {
          if (!mounted) return;
          setState(() {
            _shouldRunAnimation = false;
          });
        });
    
    

    This won't restrict Flutter versions < 3.0 and won't introduce any issues

    opened by Tkko 8
  • Broken in Flutter version 2.0.0

    Broken in Flutter version 2.0.0

    ../../../../../../SDK/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_staggered_animations-0.1.2/lib/src/animation_configuration.dart:161:20: Error: The method 'ancestorWidgetOfExactType' isn't defined for the cl ass 'BuildContext'.

    • 'BuildContext' is from 'package:flutter/src/widgets/framework.dart' ('../../../../../../SDK/flutter/packages/flutter/lib/src/widgets/framework.dart'). Try correcting the name to the name of an existing method, or defining a method named 'ancestorWidgetOfExactType'. return context.ancestorWidgetOfExactType(AnimationConfiguration) ^^^^^^^^^^^^^^^^^^^^^^^^^ ../../../../../../SDK/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_staggered_animations-0.1.2/lib/src/animation_limiter.dart:75:20: Error: The method 'ancestorWidgetOfExactType' isn't defined for the class 'Bu ildContext'.
    • 'BuildContext' is from 'package:flutter/src/widgets/framework.dart' ('../../../../../../SDK/flutter/packages/flutter/lib/src/widgets/framework.dart'). Try correcting the name to the name of an existing method, or defining a method named 'ancestorWidgetOfExactType'. return context.ancestorWidgetOfExactType(_AnimationLimiterProvider) ^^^^^^^^^^^^^^^^^^^^^^^^^
    bug 
    opened by M123-dev 7
  • Animation doesn't play when list is refreshed with StreamBuilder

    Animation doesn't play when list is refreshed with StreamBuilder

    If I wrap ListView with staggeredList animation from the example code inside StreamBuilder, animation plays on the first run, but does not play when stream builder calls the builder a 2nd time.

    opened by Gintasz 5
  • Staggered List doesn't work when used with FutureBuilder

    Staggered List doesn't work when used with FutureBuilder

    Here is my code: `FutureBuilder<List>( future: MenuService.getMenuCategory(), initialData: [], builder: (ctx, snapshot) { return AnimationLimiter( child: ListView.builder( shrinkWrap: true, scrollDirection: Axis.horizontal, itemCount: snapshot.data.length, physics: BouncingScrollPhysics(), itemBuilder: (chipCtx, index) { final isCatSelected = _selectedCategories .contains(snapshot.data[index]);

                                return AnimationConfiguration.staggeredList(
                                  position: index,
                                  duration: Duration(seconds: 5),
                                  child: FadeInAnimation(
                                    child: Container(
                                      margin: const EdgeInsets.only(
                                          left: 5.0, right: 5.0),
                                      child: FilterChip(
                                        label: Text(
                                          snapshot.data[index],
                                          style: isCatSelected &&
                                                  !_isAllCatSelected
                                              ? Theme.of(context)
                                                  .textTheme
                                                  .copyWith(
                                                    caption: TextStyle(
                                                        color: Colors.white),
                                                  )
                                                  .caption
                                              : Theme.of(context)
                                                  .textTheme
                                                  .caption,
                                        ),
                                        backgroundColor:
                                            isCatSelected && !_isAllCatSelected
                                                ? Theme.of(context).primaryColor
                                                : Colors.transparent,
                                        shape: StadiumBorder(
                                          side: BorderSide(
                                            color:
                                                Theme.of(context).primaryColor,
                                            width: 1.5,
                                          ),
                                        ),
                                        onSelected: (isSelected) {
                                          if (isSelected) {
                                            if (isCatSelected) {
                                              setState(() {
                                                _isAllCatSelected = false;
                                                _selectedCategories.removeWhere(
                                                    (category) =>
                                                        category ==
                                                        snapshot.data[index]);
                                              });
                                            } else {
                                              setState(() {
                                                _isAllCatSelected = false;
                                                _selectedCategories
                                                    .add(snapshot.data[index]);
                                              });
                                            }
                                          }
                                        },
                                      ),
                                    ),
                                  ),
                                );
                              },
                            ),
                          );
                        },
                      ),`
    

    Here is my code used for staggered animation. This works absolutely fine if I removed FutureBuilder and used any hard coded list.

    opened by utkarsh-UK 5
  • Migrate to null safety

    Migrate to null safety

    opened by nilsreichardt 4
  • A ScrollController was used after being disposed.

    A ScrollController was used after being disposed.

    A ScrollController was used after being disposed.

    When the exception was thrown, this was the stack: 
    #0      ChangeNotifier._debugAssertNotDisposed.<anonymous closure> (package:flutter/src/foundation/change_notifier.dart:105:9)
    #1      ChangeNotifier._debugAssertNotDisposed (package:flutter/src/foundation/change_notifier.dart:111:6)
    #2      ChangeNotifier.addListener (package:flutter/src/foundation/change_notifier.dart:141:12)
    #3      _FadingEdgeScrollViewState.initState (package:fading_edge_scrollview/src/fading_edge_scrollview.dart:128:17)
    

    _controller.addListener(_onScroll); in the _FadingEdgeScrollViewState

    This happens when I'm refreshing my list. Everything works great the first time. As soon as the rebuild happens it throws an error.

    opened by anisalibegic 4
  • Resize items of the list

    Resize items of the list

    I have tried to use your example in 2 ways:

    1. using the example of the ListView but on an horizontal-scroll list
    2. using the example of the GridView as it is

    In both of the cases, I have tried in many ways to resize width and/or height of the elements of myChildList...however, in both cases it has not been possible, they keep showing taking the full height in the case of the ListView, and in some sort of pre-defined height and width for the GridView.

    Can you help with that? how to achieve the desired width and height of the child items?

    documentation 
    opened by andreddie81 4
  • Support for wrapping the resulting widget in AnimationConfiguration.toStaggeredList() in another widget, also in an Expanded widget

    Support for wrapping the resulting widget in AnimationConfiguration.toStaggeredList() in another widget, also in an Expanded widget

    This adds a new optional parameter wrapperBuilder in the helper function AnimationConfiguration.toStaggeredList().

    This function can be used to wrap the resulting widget of a child widget, located at any index in the children list, in another widget.

    Declaration Widget? Function(int index, Widget child)? wrapperBuilder

    Motivation This helper function wraps each of the children in a AnimationConfiguration.staggeredList. So, you cannot wrap your widget in a Expanded or Flexible widget, as they needs to be directly placed under a Flex widget like Row or Column. This function gives the opportunity to do that, by letting you wrap the resulting widget wrapped in AnimationConfiguration.staggeredList, in another widget.

    Use Cases: This function can be used to wrap your widget in Expanded or Flex widget.

    How to use? If you want to wrap the resulting child widget at index 2 in your children list in an Expanded widget, you can do that using this function like this:

    wrapperBuilder: (index, child) {
      if (index == 2) {
        return Expanded(
          child: child,
        );
      }
      return null;
    },
    

    if null is returned, the resulting widget wrapped in AnimationConfiguration.staggeredList is used.

    The parameter is optional. If not passed, the resulting widgets wrapped in AnimationConfiguration.staggeredList are used.

    opened by souradeep98 0
  • How can i apply slide navigation to listView items.

    How can i apply slide navigation to listView items.

    Hi Basically i have simply screen with 1 question and dynamic answers and for that i have uses 1 text and ListView for dynamic answers so i want to animate question answers from right to left.

    1st question ==> all answers animate from right to left. 2nd question ==> all answers animate from right to left.

    I have do the below but it animate always 1st time. Animation not applied for rest of the questions answers listview.

    return AnimationLimiter(
          child: ListView.builder(
            shrinkWrap: true,
            physics: const NeverScrollableScrollPhysics(),
            scrollDirection: Axis.vertical,
            itemCount: answers!.answers![queCount].options!.length,
            itemBuilder: (ctx, i) {
              return AnimationConfiguration.staggeredList(
                position: i,
                duration: const Duration(milliseconds: 1000),
                child: SlideAnimation(
                  horizontalOffset: 500.0,
                  child: Container(
                    margin: const EdgeInsets.symmetric(vertical: 8),
                    padding: const EdgeInsets.all(12),
                    alignment: Alignment.center,
                    decoration: BoxDecoration(
                      gradient: answers!.answers![queCount].options![i].checked!
                          ? const RadialGradient(
                              center: Alignment(-0.8, -0.6),
                              colors: [
                                Color.fromRGBO(0, 174, 239, 0.22),
                                Color.fromRGBO(0, 174, 239, 0)
                              ],
                              radius: 4.8,
                            )
                          : null,
                      border: Border.all(color: ColorCodes.blueColor, width: 1),
                      borderRadius: BorderRadius.circular(10),
                    ),
                    child: Text(
                      answers!.answers![queCount].options![i].name ?? "",
                      textAlign: TextAlign.center,
                    ),
                  ),
                ),
              );
            },
          ),
        );
    

    How can i apply effect for all question answers?

    opened by KuldeepAIP 0
  • Only works on First Build... I have to use flutter's auto_restart everytime I want to see the scroll animation

    Only works on First Build... I have to use flutter's auto_restart everytime I want to see the scroll animation

    Don't know why but staggered_animations only works on the first build... I even added auto_refresh from the example given and whenever it builds, It builds it completely from scratch again which is every 2 seconds

    opened by OlaiyaO 1
  • Issue with OpenContainer

    Issue with OpenContainer

    Will return

    Another exception was thrown: Animation not wrapped in an AnimationConfiguration.
    

    if used within an OpenContainer, and then click on object of that list. Here is my code

    AnimationLimiter(
            child: ListView.separated(
              //...
              itemBuilder: (context, index) => AnimationConfiguration.staggeredList(
                position: index,
                duration: Duration(milliseconds: 400),
                child: OpenContainer(
                   //...
                  openBuilder: (context, _) => ProductPage(
                    product: Product.products[index],
                  ),
                  closedBuilder: (context, VoidCallback openContainer) =>
                      SlideAnimation(
                    horizontalOffset: 500.w,
                    child: Container(
                      //...
                      child: GestureDetector(
                         //...
                        child: ProductWidget(
                          product: Product.products[index],
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ),
    opened by nashirat 0
  • Flutter web, doesn't work well with GridView.builder

    Flutter web, doesn't work well with GridView.builder

    seeing this in the console:

    ════════ Exception caught by animation library ═════════════════════════════════ The provided ScrollController is currently attached to more than one ScrollPosition. ════════════════════════════════════════════════════════════════════════════════

    Also scrolling doesn't update unless you scroll up a bunch to trigger it. And very slow.

    opened by sgehrman 0
Releases(1.0.0)
  • 1.0.0(Mar 8, 2021)

  • 0.1.3(Mar 4, 2021)

  • 0.1.2(Sep 11, 2019)

Owner
null
🐱‍👤 Flutter-Animation 🔥 🔥 List Animated Staggered Animations

??‍?? Staggered Animations made with algeria ❤

Hmida 17 Nov 22, 2022
Beautiful Animated ListView and GridView

staggered_animated_listview Beautiful Animated ListView and GridView Online Preview Getting Started This project is a starting point for a Flutter app

Elyas Sekhavati Nia 1 Dec 11, 2021
Flutter ListView and GridView that shows Loading Widgets before the real data is loaded.

loadinglistview This package provide an easy way to show loading indicator(Widget) in a listview or a gridview while the app is still fetching the rea

null 3 Dec 8, 2021
Arisstaggeredgridview - Staggered Grid View For Flutter

Flutter - StaggeredGridView We complete the design challenge by integrating a St

Behruz Hurramov 2 Jan 9, 2022
Fade animation - Add fade animation to your app easily

fade_animation Add fade animation to your app easily using simple_animations pac

Mazouzi Aymene 3 Oct 6, 2022
Create powerful animations in Flutter and use the hero animation for complex animations

Hero Animation - Locations UI - Flutter Create powerful animations in Flutter and use the hero animation for complex animations. ⚡  Social Media  Twit

null 3 Dec 11, 2021
A new Flutter dialog with a series of beautiful animations, slide fade rotate size scale rotate3D animations.

flutter_animated_dialog A new Flutter dialog with a series of beautiful animations, slide fade rotate size scale rotate3D animations. Dialog barrier i

null 20 Dec 3, 2022
A light weight library to easily manage a progress dialog with simple steps whenever you need to do it. You can easily show and hide it.

progress_dialog A light weight package to show progress dialog. As it is a stateful widget, you can change the text shown on the dialog dynamically. T

Mohammad Fayaz 202 Dec 11, 2022
A collection of Screens and attractive UIs built with Flutter ready to be used in your applications. No external libraries are used. Just download, add to your project and use.

Flutter Screens A collection of Login Screens, Buttons, Loaders and Widgets with attractive UIs, built with Flutter, ready to be used in your applicat

Samarth Agarwal 5k Dec 31, 2022
Custom Layout with interactive add button to impove your UI and UX .

Interactive Add button layout Custom Layout with interactive add button to impove your UI and UX . the package is available here inspired from Oleg Fr

Dokkar Rachid Reda 20 Sep 13, 2021
Organize your animations.

montage Organize your animations. Quickstart // 1. Define your animations const entrance = MontageAnimation( key: 'entrance', duration: Duration(s

Aloïs Deniel 14 Oct 19, 2022
Simple reactive animations in your Flutter apps.

just.motion Flutter package to create organic motion transitions. Why? The Motion Value stateless hot reload status notifier Ease Motion Spring Motion

Roi Peker 49 Nov 14, 2022
A collection of Animations that aims to improve the user experience for your next flutter project.

A collection of Animations that aims to improve the user experience for your next flutter project.

Ezaldeen Sahb 134 Dec 24, 2022
A Flutter ListView that implicitly animates between the changes of two lists with support to reorder its items.

Implicitly Animated Reorderable List A Flutter ListView that implicitly calculates the changes between two lists using the MyersDiff algorithm and ani

null 246 Feb 22, 2022
A Flutter ListView that implicitly animates between the changes of two lists with support to reorder its items.

Implicitly Animated Reorderable List A Flutter ListView that implicitly calculates the changes between two lists using the MyersDiff algorithm and ani

null 246 Feb 22, 2022
🔔 A flutter package to create cool and beautiful text animations. [Flutter Favorite Package]

Animated Text Kit A flutter package which contains a collection of some cool and awesome text animations. Recommended package for text animations in C

Ayush Agarwal 1.4k Jan 6, 2023
Fun canvas animations in Flutter based on time and math functions.

funvas Flutter package that allows creating canvas animations based on time and math (mostly trigonometric) functions. The name "funvas" is based on F

null 472 Jan 9, 2023
A widget for stacking cards, which users can swipe horizontally and vertically with beautiful animations.

A widget for stacking cards, which users can swipe horizontally and vertically with beautiful animations.

HeavenOSK 97 Jan 6, 2023
A catalog of beautiful, reusable and elegant animations

Animations Catalog The goal of this project is to catalog and build multiple animation patterns with flutter. Budget App Animation Harley Swipe To Enl

null 3 Sep 6, 2021