3

The floatingActionButton property of Scaffold accepts any widget, so I use there a row of a few custom containers to take advantage of the floating effect. I've set the floatingActionButtonLocation property to "centerFloat". The problem is, that whenever I push a new page with such a widget, it uses a weird animation that I want to disable. I found this: Disable Scaffold FAB animation, so I extended FloatingActionButtonAnimator and tried what was shown in the aforementioned example, but unfortunately, it didn't help. I dealt with the offset easily. but the rotation and scale animation persist. Even tweaking the begin and end values of the Tween object doesn't help.

This is the setup in the Scaffold:

    floatingActionButton: ActionControls(),
    floatingActionButtonLocation:
        FloatingActionButtonLocation.centerFloat,
    floatingActionButtonAnimator: NoScalingAnimation(),

Those are the ActionControls, that are basically my floating buttons:

class ActionControls extends StatelessWidget {
  Widget _iconButton({
    @required BuildContext context,
    @required IconData icon,
    @required Function function,
    Color color,
  }) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(5),
        color: color == null ? Theme.of(context).accentColor : color,
      ),
      child: IconButton(
        icon: Icon(
          icon,
          size: 30,
          color: Colors.white,
        ),
        onPressed: function,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        _iconButton(
          context: context,
          icon: Icons.keyboard_arrow_left,
          function: () {},
        ),
        const SizedBox(width: 10),
        _iconButton(
          context: context,
          icon: Icons.add,
          function: () {},
        ),
      ],
    );
  }
}

And this is my FloatingActionButtonAnimator:

class NoScalingAnimation extends FloatingActionButtonAnimator {
  @override
  Offset getOffset({Offset begin, Offset end, double progress}) {
    return end;
  }

  @override
  Animation<double> getRotationAnimation({Animation<double> parent}) {
    return Tween<double>(begin: 1.0, end: 1.0).animate(parent);
  }

  @override
  Animation<double> getScaleAnimation({Animation<double> parent}) {
    return Tween<double>(begin: 1.0, end: 1.0).animate(parent);
  }
}

Problematic animation example: https://i.stack.imgur.com/Rf0OS.jpg

1 Answers1

4

FloatingActionButton has a parameter herotag, if you do not define it it will use a defaultHeroTag, when pushing to a new page it checks herotags with same name an apply the animation.

FloatingActionButton(
  heroTag: "MyFirstPage", //give it a custom name to avoid same heroTag in each page
  ...
 )

UPDATE

class First extends StatelessWidget{

   @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('First'),
            RaisedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => Second(),
                  ),
                );
              },
              child: Text('Page'),
            ),
          ],
        ),
      ),
      floatingActionButton: ActionControls(),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButtonAnimator: NoScalingAnimation(),
    );
  }
}

class Second extends StatelessWidget{

  @override
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(),
      body: Center(child: Text('My Second Page')),
      floatingActionButton: ActionControls(),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButtonAnimator: NoScalingAnimation(),
      /*
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () => print('tapped')
      ),
      */
    );
  }
}

class ActionControls extends StatelessWidget {
  Widget _iconButton({
    @required BuildContext context,
    @required IconData icon,
    @required Function function,
    Color color,
  }) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(5),
        color: color == null ? Theme.of(context).accentColor : color,
      ),
      child: IconButton(
        icon: Icon(
          icon,
          size: 30,
          color: Colors.white,
        ),
        onPressed: function,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        _iconButton(
          context: context,
          icon: Icons.keyboard_arrow_left,
          function: () {},
        ),
        const SizedBox(width: 10),
        _iconButton(
          context: context,
          icon: Icons.add,
          function: () {},
        ),
      ],
    );
  }
}

class NoScalingAnimation extends FloatingActionButtonAnimator {
  @override
  Offset getOffset({Offset begin, Offset end, double progress}) {
    return end;
  }

  @override
  Animation<double> getRotationAnimation({Animation<double> parent}) {
    return Tween<double>(begin: 1.0, end: 1.0).animate(parent);
  }

  @override
  Animation<double> getScaleAnimation({Animation<double> parent}) {
    return Tween<double>(begin: 1.0, end: 1.0).animate(parent);
  }
}

I made a minimal reproducible code sample and I didn't found any animation between the first and second page, even changing in the second page the position to FloatingActionButtonLocation.endFloat or actually inserting a FloatingActionButton(). The only animation I see is from the MaterialPageRoute fade from below animation

EdwynZN
  • 4,895
  • 2
  • 12
  • 15
  • I am not using an actual FloatingActionButton, but other custom widgets, so there is no a heroTag field. –  Jun 03 '20 at 19:31
  • Weird, your example works perfectly, but my project is the same and causes issues. I will try to debug this again. I also added a video example of the animation. Thanks for the help, anyway! –  Jun 03 '20 at 21:12
  • Ok, I started rebuilding the page from scratch and for now everything is good. I will treat this question as answered. –  Jun 03 '20 at 21:22