Search code examples
flutterdartfloating-action-button

FloatingActionButton Animation rebuilds on scroll


I am using a FloatingActionButton in my app. My Code looks like this:

@override
Widget build(BuildContext context) {
    return Scaffold(
        floatingActionButton: new Visibility(
            visible: _fabIsVisible,
            child: FloatingActionButton(
              onPressed: () {
                webView.scrollTo(x: 0, y: 0, animated: true);
              },
              child: Icon(Icons.arrow_upward),
              backgroundColor: Theme.of(context).primaryColor,
            )),
        floatingActionButtonLocation: MarginEndFloatFABLocation(),
        appBar: new TopBar(widget.articlePreview.url),
        body: Builder(builder: (BuildContext context) {
          return Container();
        }));
  }

class MarginEndFloatFABLocation extends StandardFabLocation with FabEndOffsetX, FabFloatOffsetY {
  @override
  double getOffsetY(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
    final double directionalAdjustment = scaffoldGeometry.textDirection == TextDirection.ltr ? -50.0 : 50.0;
    return super.getOffsetY(scaffoldGeometry, adjustment) + directionalAdjustment;
  }
}

Inside my Container with the content is a InAppWebView. When I scroll the content this happens to the button:

enter image description here

That is when I added: floatingActionButtonAnimator: NoFABAnimation(),

class NoFABAnimation extends FloatingActionButtonAnimator {
  double _x;
  double _y;

  @override
  Offset getOffset({Offset begin, Offset end, double progress}) {
    _x = begin.dx + (end.dx - begin.dx) * progress;
    _y = begin.dy + (end.dy - begin.dy) * progress;
    return Offset(_x, _y);
  }

  @override
  Animation<double> getRotationAnimation({Animation<double> parent}) {
    return parent;
  }

  @override
  Animation<double> getScaleAnimation({Animation<double> parent}) {
    return parent;
  }
}

But after adding this I get this behaviour:

enter image description here

I like the animation itself. I'd like if it would appear every time I make the button visible. But now the button is always hidden on scrolling and reappers afterwards. And this is definitely not related to my Visibility-clause as this happens exactly the same if I execute my code without this.

Anyone knows what I am doing wrong here or how I can prevent this FAB-behaviour?

I guess the build is somehow called when scrolling in the webview an this causes the animation to start again?


Solution

  • Ohh I just found the answer myself. I had this listener in my inappwebview:

    onScrollChanged: (InAppWebViewController controller, int x, int y) {
        if (y > 0) {
            setState(() {
              _fabIsVisible = true;
            });
        } else {
            setState(() {
              _fabIsVisible = false;
            });
        }
    }
    

    I changed it so it only calls setState if there is really a change. This solved my problem.

    onScrollChanged: (InAppWebViewController controller, int x, int y) {
        if (y > 0) {
          if (!_fabIsVisible) {
            setState(() {
              _fabIsVisible = true;
            });
          }
        } else {
          if (_fabIsVisible) {
            setState(() {
              _fabIsVisible = false;
            });
          }
        }
      }