AndreHaueisen / flushbar

Custom widget for Flutter
Other
1.01k stars 172 forks source link

Push widget upward when snackbar is showing #64

Open antonygunawan94 opened 5 years ago

antonygunawan94 commented 5 years ago

Hello,

I want to ask if there is any features to these kind of behaviour https://medium.com/@phaniraja/overlap-issue-with-snackbar-df49e25be407

Thank you

AndreHaueisen commented 5 years ago

Hello @antonygunawan94 So far there are two possible workarounds, but they are not ideal 1- You can give more padding to FLushbar bar so it can go beyond the limits of the view you don't want to obscure. Use aroundPadding 2- Can set overlayBlur > 0 so the UI don't get confusing.

I don't know if this can be done since we are using a new overlay to show the notification, but I will do some research. This indeed would be a cool feature. Thanks for the feedback.

hydeparkk commented 4 years ago

I had to deal with the same problem and found workaround that works and suits my needs. Preview

The only problem with this solution is that I've couldn't get dimensions and position of flushbar, so tha padding in wrapper is hardcoded and for me works well with my one line fliushbars, but if the size of the flushbar is not constant it should be fitted better.

import 'package:flushbar/flushbar.dart';
import 'package:flushbar/flushbar_route.dart';
import 'package:flutter/material.dart';

class FlushbarRouteObserver extends RouteObserver<PageRoute<dynamic>>
    with ChangeNotifier {
  FlushbarStatus status;
  Flushbar flushbar;

  static final FlushbarRouteObserver _instance =
      FlushbarRouteObserver._internal();

  factory FlushbarRouteObserver() => _instance;

  FlushbarRouteObserver._internal();

  @override
  void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
    super.didPop(route, previousRoute);
    if (route is FlushbarRoute) {
      status = route.currentStatus;
      flushbar = null;
      notifyListeners();
    }
  }

  @override
  void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
    super.didPush(route, previousRoute);
    if (route is FlushbarRoute) {
      flushbar = route.flushbar;
      status = route.currentStatus;
      notifyListeners();
    }
  }
}

// Add it to navigatorObservers in MaterialApp
return MaterialApp(
  navigatorObservers: [
      // ...
      FlushbarRouteObserver(),
  ],
  // ...
);

// And create wrapper for FAB widget
class FABWRapper extends StatefulWidget {
  @override
  FABWRapperState createState() =>
      FABWRapperState();
}

class FABWRapperState extends State<FABWRapper> {
  EdgeInsets _padding = EdgeInsets.zero;

  final flushbarRouteObserver = FlushbarRouteObserver();

  @override
  void initState() {
    super.initState();
    flushbarRouteObserver.addListener(_flushbarListener);
  }

  @override
  void dispose() {
    flushbarRouteObserver.removeListener(_flushbarListener);
    super.dispose();
  }

  void _flushbarListener() {
    EdgeInsets padding;
    switch (flushbarRouteObserver.status) {
      case FlushbarStatus.IS_APPEARING:
        padding = EdgeInsets.only(bottom: 60.0);
        break;
      case FlushbarStatus.IS_HIDING:
        padding = EdgeInsets.zero;
        break;
      default:
        break;
    }

    setState(() {
      _padding = padding;
    });
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedPadding(
      duration: Duration(milliseconds: 450),
      padding: _padding,
      child: FloatingActionButton(),   
    );
  }
}
PembaTamang commented 4 years ago

I have done it by placing the fab in an AnimatedPositioned which needs to be in a stack. I animate the bottom positon when the FlushBar is appearning or hiding.

   floatingActionButton: Stack(
        children: [
          AnimatedPositioned(
            left: 0,
            right: 0,
            bottom: _bottom,
            duration: Duration(seconds: 1),
            child: FloatingActionButton(
              onPressed: () {
                Flushbar(
                  message: 'Hi There',
                  flushbarPosition: FlushbarPosition.BOTTOM,
                  flushbarStyle: FlushbarStyle.FLOATING,
                  duration: Duration(seconds: 2),
                  barBlur: 4.0,
                  onStatusChanged:(status){
                    print(status);
                    if(status == FlushbarStatus.IS_APPEARING){
                      setState(() {
                       _bottom = 55;

                      });
                    }else if(status == FlushbarStatus.IS_HIDING){
                      setState(() {
                        _bottom  = 0;

                      });
                    }

                  } ,
                ).show(context);
              },
              child: Icon(
                Icons.category,
                color: Colors.black45,
              ),
              backgroundColor: Colors.orangeAccent,
            ),
          ),
        ],
      ),