1

Hi I use Provider (https://pub.dev/packages/provider) into my Flutter app. Now I want to manage the floating action button into a scaffold using a provider consumer, to be sure that the scaffold is not rebuilded when I need to hide the FAB button.

Now I've created a simple FABProvider

class FABProvider extends ChangeNotifier {
  FABProvider(bool initialValue) {
    this._visible = initialValue;
  }

  bool _visible;
  bool get visible => _visible;

  void hide() {
    if (_visible) {
      _visible = false;
      notifyListeners();
    }
  }

  void show() {
    if (!_visible) {
      _visible = true;
      notifyListeners();
    }
  }
}

I wrap all Scaffold into a ChangeNotifierProvider:

    return ChangeNotifierProvider<FABProvider>.value(
      value: fabProvider,
      child: Scaffold(
      ...
             floatingActionButton: Consumer<FABProvider>(
                 child: createMyFAB(),
                 builder: (context, provider, child) {
                    if (provider.visible) {
                       return child;
                    } else {
                       return null;   <-- Now I need to return null when the fab need to be hided otherwise the scaffold does not animate the FAB 
                    }
                 },
             ),
      ...

      )
      ...

I try also return an Offstage() or a Container(), but when return a Widget and not null the Scaffold does not animate the fab visibility.

Massimo Caroccia
  • 417
  • 2
  • 6
  • 14
  • 1
    You can use an `AnimatedCrossFade` or `AnimatedSwitcher` widget to animate the `visibility` of your `fab`. – void Aug 09 '20 at 15:47

1 Answers1

0

If you're using Provider 4.1.0 or above you can use the parameter builder that let you use the provider above instead of using a Consumer (that forces you to return a Widget, so you can't use null), that way you can return null to the floatingActionButton and fire the animation when changes (predetermined to scaling)

return ChangeNotifierProvider<FABProvider>.value(
  value: fabProvider,
  builder: (context, child) {
    final visible = context.select((FABProvider fab) => fab.visible);
    return Scaffold(
      floatingActionButton: visible ? createMyFAB() : null
      ...
  }
)
EdwynZN
  • 4,895
  • 2
  • 12
  • 15
  • Yes this work but this solution rebuild all scaffold and I don't want this. – Massimo Caroccia Aug 09 '20 at 16:40
  • The Derek solution is good, the only problem is that I need to manually handle the Fab animation, but work without Scaffold rebuild – Massimo Caroccia Aug 09 '20 at 16:41
  • Derek solution is the best if you want to avoid unnecessary rebuilds, but as you said, you have to implement your own animation (or using AnimatedSwitcher) – EdwynZN Aug 09 '20 at 17:13
  • Using the animation widgets I mentioned above are simple since they are implicit animations. All you need is provide the `two widgets` to switch between and `duration` of the animation. – void Aug 09 '20 at 17:18