Git Product home page Git Product logo

cmdrootaccess / another-flushbar Goto Github PK

View Code? Open in Web Editor NEW
144.0 2.0 87.0 1.17 MB

A flexible widget for user notification. Customize your text, button, duration, animations and much more. For Android devs, it is made to replace Snackbars and Toasts.

Home Page: https://pub.dev/packages/another_flushbar

License: MIT License

Kotlin 0.27% Ruby 2.51% Swift 0.75% Objective-C 0.07% Dart 91.97% Java 1.03% HTML 3.41%
flushbar flutter

another-flushbar's Introduction

another_flushbar

Pub

Use this package if you need more customization when notifying your user. For Android developers, it is made to substitute toasts and snackbars. IOS developers, I don't know what you use there, but you will like it.

See the install instructions.

Quick reference

Since customization requires a lot of properties, here is a quick cheatsheet:

Property What does it do
title The title displayed to the user
titleColor The title color displayed to the user
titleSize The title size displayed to the user
message The message displayed to the user.
messageColor The message color displayed to the user.
messageSize The message size displayed to the user.
titleText Replaces [title]. Although this accepts a [widget], it is meant to receive [Text] or [RichText]
messageText Replaces [message]. Although this accepts a [widget], it is meant to receive [Text] or [RichText]
icon You can use any widget here, but I recommend [Icon] or [Image] as indication of what kind of message you are displaying. Other widgets may break the layout
shouldIconPulse An option to animate the icon (if present). Defaults to true.
maxWidth Used to limit Flushbar width (usually on large screens)
margin Adds a custom margin to Flushbar
padding Adds a custom padding to Flushbar. The default follows material design guide line
borderRadius Adds a radius to specified corners of Flushbar. Best combined with [margin]. I do not recommend using it with [showProgressIndicator] or [leftBarIndicatorColor]
textDirection [TextDirection.ltr] by default. [Directionality.of(context)] to know whether it would be [TextDirection.ltr] or [TextDirection.rtl]
borderColor Adds a border to every side of Flushbar. I do not recommend using it with [showProgressIndicator] or [leftBarIndicatorColor]
borderWidth Changes the width of the border if [borderColor] is specified
backgroundColor Flushbar background color. Will be ignored if [backgroundGradient] is not null.
leftBarIndicatorColor If not null, shows a left vertical bar to better indicate the humor of the notification. It is not possible to use it with a [Form] and I do not recommend using it with [LinearProgressIndicator].
boxShadows The shadows generated by Flushbar. Leave it null if you don't want a shadow. You can use more than one if you feel the need. Check this example
backgroundGradient Flushbar background gradient. Makes [backgroundColor] be ignored.
mainButton Use if you need an action from the user. [FlatButton] is recommended here.
onTap A callback that registers the user's click anywhere. An alternative to [mainButton]
duration How long until Flushbar will hide itself (be dismissed). To make it indefinite, leave it null.
isDismissible Determines if the user can swipe or click the overlay (if [routeBlur] > 0) to dismiss. It is recommended that you set [duration] != null if this is false. If the user swipes to dismiss or clicks the overlay, no value will be returned.
dismissDirection FlushbarDismissDirection.VERTICAL by default. Can also be [FlushbarDismissDirection.HORIZONTAL] in which case both left and right dismiss are allowed.
flushbarPosition Flushbar can be based on [FlushbarPosition.TOP] or on [FlushbarPosition.BOTTOM] of your screen. [FlushbarPosition.BOTTOM] is the default.
flushbarStyle Flushbar can be floating or be grounded to the edge of the screen. If grounded, I do not recommend using [margin] or [borderRadius]. [FlushbarStyle.FLOATING] is the default
forwardAnimationCurve The [Curve] animation used when show() is called. [Curves.easeOut] is default.
reverseAnimationCurve The [Curve] animation used when dismiss() is called. [Curves.fastOutSlowIn] is default.
animationDuration Use it to speed up or slow down the animation duration
showProgressIndicator true if you want to show a [LinearProgressIndicator]. If [progressIndicatorController] is null, an infinite progress indicator will be shown
progressIndicatorController An optional [AnimationController] when you want to control the progress of your [LinearProgressIndicator]. You are responsible for controlling the progress
progressIndicatorBackgroundColor a [LinearProgressIndicator] configuration parameter.
progressIndicatorValueColor a [LinearProgressIndicator] configuration parameter.
barBlur Default is 0.0. If different than 0.0, blurs only Flushbar's background. To take effect, make sure your [backgroundColor] has some opacity. The greater the value, the greater the blur.
blockBackgroundInteraction Determines if user can interact with the screen behind it. If this is false, [routeBlur] and [routeColor] will be ignored
routeBlur Default is 0.0. If different than 0.0, creates a blurred overlay that prevents the user from interacting with the screen. The greater the value, the greater the blur. It does not take effect if [blockBackgroundInteraction] is false
routeColor Default is [Colors.transparent]. Only takes effect if [routeBlur] > 0.0. Make sure you use a color with transparency e.g. Colors.grey[600].withOpacity(0.2). It does not take effect if [blockBackgroundInteraction] is false
userInputForm A [TextFormField] in case you want a simple user input. Every other widget is ignored if this is not null.
onStatusChanged a callback for you to listen to the different Flushbar status

Quick tip

If you use a lot of those properties, it makes sense to make a factory to help with your Flushbar's base appearance. Things like shadows, padding, margins, text styles usually don't change within the app. Take a look at FlushbarHelper class and use it as an example.

We are on YouTube!

While studying Flutter I stumbled on two amazing tutorials on how to use Flushbar. Make sure you show those guys some love.

  1. A beginners tutorial by Matej Rešetár
  2. A more advanced usage by Javier González Rodríguez

Getting Started

The examples bellow were updated for version 1.3.0. Changes might have been made. See the changelog if any of the examples do not reflect Flushbar's current state.

The possibilities

Flushbar Animated

A basic Flushbar

The most basic Flushbar uses only a message. Failing to provide it before you call show() will result in a runtime error. Duration, if not provided, will create an infinite Flushbar, only dismissible by code, back button clicks, or a drag (case isDismissible is set to true).

  • Note that only message is a required parameter. All the other ones are optional
class YourAwesomeApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'YourAwesomeApp',
      home: Scaffold(
        Container(
          child: Center(
            child: MaterialButton(
              onPressed: (){
                Flushbar(
                  title:  "Hey Ninja",
                  message:  "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
                  duration:  Duration(seconds: 3),
                )..show(context);
              },
            ),
          ),
        ),
      ),
    );
  }
}

Basic Example

Lets get crazy Flushbar

Here is how customized things can get.

Flushbar(
      title: "Hey Ninja",
      titleColor: Colors.white,
      message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
      flushbarPosition: FlushbarPosition.TOP,
      flushbarStyle: FlushbarStyle.FLOATING,
      reverseAnimationCurve: Curves.decelerate,
      forwardAnimationCurve: Curves.elasticOut,
      backgroundColor: Colors.red,
      boxShadows: [BoxShadow(color: Colors.blue[800], offset: Offset(0.0, 2.0), blurRadius: 3.0)],
      backgroundGradient: LinearGradient(colors: [Colors.blueGrey, Colors.black]),
      isDismissible: false,
      duration: Duration(seconds: 4),
      icon: Icon(
        Icons.check,
        color: Colors.greenAccent,
      ),
      mainButton: FlatButton(
        onPressed: () {},
        child: Text(
          "CLAP",
          style: TextStyle(color: Colors.amber),
        ),
      ),
      showProgressIndicator: true,
      progressIndicatorBackgroundColor: Colors.blueGrey,
      titleText: Text(
        "Hello Hero",
        style: TextStyle(
            fontWeight: FontWeight.bold, fontSize: 20.0, color: Colors.yellow[600], fontFamily: "ShadowsIntoLightTwo"),
      ),
      messageText: Text(
        "You killed that giant monster in the city. Congratulations!",
        style: TextStyle(fontSize: 18.0, color: Colors.green, fontFamily: "ShadowsIntoLightTwo"),
      ),
    );

Complete Example

  • Don't forget to call show() or the bar will stay hidden.
  • To deactivate any of those properties, pass null to it.

Styles

Flushbar can be either floating or grounded to the edge of the screen. I don't recommend using margin or borderRadius if you chose FlushbarStyle.GROUNDED style.

Flushbar(flushbarStyle: FlushbarStyle.FLOATING)

or

Flushbar(flushbarStyle: FlushbarStyle.GROUNDED)
Floating Style Grounded Style
Floating Style Grounded Style

Padding and Border Radius

You can give it some padding and a border radius. Works best with FlushbarStyle.FLOATING

Flushbar(
  margin: EdgeInsets.all(8),
  borderRadius: BorderRadius.circular(8),
);

Padding and Radius

Left indicator bar

Flushbar has a lateral bar to better convey the humor of the notification. To use it, simple give leftBarIndicatorColor a color.

Flushbar(
  message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
  icon: Icon(
    Icons.info_outline,
    size: 28.0,
    color: Colors.blue[300],
    ),
  duration: Duration(seconds: 3),
  leftBarIndicatorColor: Colors.blue[300],
)..show(context);

Left indicator example

Customize your text

If you need a more fancy text, you can use Text or RichText and pass it to the titleText or messageText variables.

  • Note that title will be ignored if titleText is not null
  • Note that message will be ignored if messageText is not null
Flushbar(
  title: "Hey Ninja", //ignored since titleText != null
  message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry", //ignored since messageText != null
  titleText: Text("Hello Hero", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0 color: Colors.yellow[600], fontFamily:"ShadowsIntoLightTwo"),),
  messageText: Text("You killed that giant monster in the city. Congratulations!", style: TextStyle(fontSize: 16.0, color: Colors.green[fontFamily: "ShadowsIntoLightTwo"),),
)..show(context);

Customized Text

Customize background and shadow

You can paint the background with any color you want. You can use any shadow you want. Just give it a backgroundColor and boxShadows.

Flushbar(
  title: "Hey Ninja",
  message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
  backgroundColor: Colors.red,
  boxShadows: [BoxShadow(color: Colors.red[800], offset: Offset(0.0, 2.0), blurRadius: 3.0,)],
)..show(context);

Background and Shadow

Want a gradient in the background? No problem.

  • Note that backgroundColor will be ignored while backgroundGradient is not null
Flushbar(
  title: "Hey Ninja",
  message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
  backgroundGradient: LinearGradient(colors: [Colors.blue, Colors.teal]),
  backgroundColor: Colors.red,
  boxShadows: [BoxShadow(color: Colors.blue[800], offset: Offset(0.0, 2.0), blurRadius: 3.0,)],
)..show(context);

Background Gradient

Icon and button action

Let us put a Icon that has a PulseAnimation. Icons have this animation by default and cannot be changed as of now. Also, let us put a button. Have you noticed that show() returns a Future? This Future will yield a value when you call dismiss([T result]). I recommend that you specify the result generic type if you intend to collect an user input.

Flushbar flush;
bool _wasButtonClicked;
@override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: MaterialButton(
          onPressed: () {
            flush = Flushbar<bool>(
              title: "Hey Ninja",
              message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
              icon: Icon(
                       Icons.info_outline,
                       color: Colors.blue,),
              mainButton: FlatButton(
                             onPressed: () {
                                 flush.dismiss(true); // result = true
                               },
                             child: Text(
                               "ADD",
                               style: TextStyle(color: Colors.amber),
                             ),
                           ),) // <bool> is the type of the result passed to dismiss() and collected by show().then((result){})
              ..show(context).then((result) {
                setState(() { // setState() is optional here
                  _wasButtonClicked = result;
                });
              });
          },
        ),
      ),
    );
  }

Icon and Button

Flushbar position

Flushbar can be at FlushbarPosition.BOTTOM or FlushbarPosition.TOP.

Flushbar(
  flushbarPosition: FlushbarPosition.TOP,
  title: "Hey Ninja",
  message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry",)..show(context);

Bar position

Duration and dismiss policy

By default, Flushbar is infinite. To set a duration, use the duration property. By default, Flushbar is dismissible by the user. A right or left drag will dismiss it. Set isDismissible to false to change this behaviour.

Flushbar(
  title: "Hey Ninja",
  message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
  duration: Duration(seconds: 3),
  isDismissible: false,
)..show(context);

Progress Indicator

If you are loading something, use a LinearProgressIndicator If you want an undetermined progress indicator, do not set progressIndicatorController. If you want a determined progress indicator, you now have full control over the progress since you own the AnimationController

  • There is no need to add a listener to your controller just to call setState(){}. Once you pass in your controller, Flushbar will do this automatically. Just make sure you call _controller.forward()
AnimationController _controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 3),
    );

Flushbar(
  title: "Hey Ninja",
  message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
  showProgressIndicator: true,
  progressIndicatorController: _controller,
  progressIndicatorBackgroundColor: Colors.grey[800],
)..show(context);

Show and dismiss animation curves

You can set custom animation curves using forwardAnimationCurve and reverseAnimationCurve.

Flushbar(
  forwardAnimationCurve: Curves.decelerate,
  reverseAnimationCurve: Curves.easeOut,
  title: "Hey Ninja",
  message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
)..show(context);

Listen to status updates

You can listen to status update using the onStatusChanged property.

  • Note that when you pass a new listener using onStatusChanged, it will activate once immediately so you can check in what state the Flushbar is.
Flushbar flushbar = Flushbar(title: "Hey Ninja", message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry");

  flushbar
    ..onStatusChanged = (FlushbarStatus status) {
      switch (status) {
        case FlushbarStatus.SHOWING:
          {
            doSomething();
            break;
          }
        case FlushbarStatus.IS_APPEARING:
          {
            doSomethingElse();
            break;
          }
        case FlushbarStatus.IS_HIDING:
          {
            doSomethingElse();
            break;
          }
        case FlushbarStatus.DISMISSED:
          {
            doSomethingElse();
            break;
          }
      }
    }
    ..show(context);

Input text

Sometimes we just want a simple user input. Use the propertyuserInputForm.

  • Note that buttons, messages, and icons will be ignored if userInputForm != null
  • dismiss(result) will yield result. dismiss() will yield null.
Flushbar<List<String>> flush;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
TextFormField getFormField(String text) {
    return TextFormField(
      initialValue: text,
      style: TextStyle(color: Colors.white),
      maxLength: 100,
      maxLines: 1,
      maxLengthEnforced: true,
      decoration: InputDecoration(
          fillColor: Colors.white10,
          filled: true,
          icon: Icon(
            Icons.label,
            color: Colors.grey[500],
          ),
          border: UnderlineInputBorder(),
          helperText: "Helper Text",
          helperStyle: TextStyle(color: Colors.grey),
          labelText: "Label Text",
          labelStyle: TextStyle(color: Colors.grey)),
    );
  }

flush = Flushbar<List<String>>(
  userInputForm = Form(
          key: _formKey,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              getTextFormField("Initial Value"),
              getTextFormField("Initial Value Two"),
            ]
            Align(
              alignment: Alignment.bottomRight,
              child: Padding(
                padding: const EdgeInsets.only(top: 8.0),
                child: MaterialButton(
                  textColor: Colors.amberAccent,
                  child: Text("SUBMIT"),
                  onPressed: () {
                    flush.dismiss([_controller1.value.text, _controller2.value.text]);
                  },
                ),
              ),
            )
          ],),),
)..show(context).then((result) {
        if (result != null) {
          String userInput1 = result[0];
          String userInput2 = result[1];
        }
      });

This example tries to mimic the Material Design style guide

Bar input

RTL text

RTL Text

You can add textDirection: Directionality.of(context) for rtl.

 Flushbar(
message: "لوريم إيبسوم هو ببساطة نص شكلي يستخدم في صناعة الطباعة والتنضيد",
icon: Icon(
Icons.info_outline,
size: 28.0,
color: Colors.blue[300],
),
margin: EdgeInsets.all(6.0),
flushbarStyle: FlushbarStyle.FLOATING,
flushbarPosition: FlushbarPosition.TOP,
textDirection: Directionality.of(context),
borderRadius: BorderRadius.circular(12),
duration: Duration(seconds: 3),
leftBarIndicatorColor: Colors.blue[300],
)..show(context);

Flushbar Helper

I made a helper class to facilitate the creation of the most common Flushbars.

FlushbarHelper.createSuccess({message, title, duration});
FlushbarHelper.createInformation({message, title, duration});
FlushbarHelper.createError({message, title, duration});
FlushbarHelper.createAction({message, title, duration flatButton});
FlushbarHelper.createLoading({message,linearProgressIndicator, title, duration, progressIndicatorController, progressIndicatorBackgroundColor});
FlushbarHelper.createInputFlushbar({textForm});

another-flushbar's People

Contributors

areille avatar cmdrootaccess avatar earminjon avatar emvaized avatar hamidwakili avatar imajeed16 avatar jasperessiendro avatar juliansteenbakker avatar robinbonnes avatar silverhairs avatar wheeos avatar x-slayer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

another-flushbar's Issues

[WEB] Undefined name 'AnotherFlushbarPlugin' in generated_plugin_registrant.dart

This bug is relative to 1.10.9 and beyond.
Downgrading to 1.10.8 resolve this issue.

Error:
lib/generated_plugin_registrant.dart:21:3: Error: Getter not found: 'AnotherFlushbarPlugin'.
AnotherFlushbarPlugin.registerWith(registrar);
^^^^^^^^^^^^^^^^^^^^^

//
// Generated file. Do not edit.
//

import 'package:another_flushbar/flushbar.dart';
import 'package:contact_picker_web/contact_picker_web.dart';
import 'package:firebase_analytics_web/firebase_analytics_web.dart';
import 'package:firebase_auth_web/firebase_auth_web.dart';
import 'package:firebase_core_web/firebase_core_web.dart';
import 'package:flutter_device_locale/src/web.dart';
import 'package:google_sign_in_web/google_sign_in_web.dart';
import 'package:location_web/location_web.dart';
import 'package:package_info_plus_web/package_info_plus_web.dart';
import 'package:shared_preferences_web/shared_preferences_web.dart';
import 'package:url_launcher_web/url_launcher_web.dart';

import 'package:flutter_web_plugins/flutter_web_plugins.dart';

// ignore: public_member_api_docs
void registerPlugins(Registrar registrar) {
  AnotherFlushbarPlugin.registerWith(registrar);
  FlutterContactPickerPlugin.registerWith(registrar);
  FirebaseAnalyticsWeb.registerWith(registrar);
  FirebaseAuthWeb.registerWith(registrar);
  FirebaseCoreWeb.registerWith(registrar);
  FlutterDeviceLocaleWebPlugin.registerWith(registrar);
  GoogleSignInPlugin.registerWith(registrar);
  LocationWebPlugin.registerWith(registrar);
  PackageInfoPlugin.registerWith(registrar);
  SharedPreferencesPlugin.registerWith(registrar);
  UrlLauncherPlugin.registerWith(registrar);
  registrar.registerMessageHandler();
}

Stack Alerts

Would be nice to implement this, taked from: original repo

I would like the ability to stack alerts on top of each other (appearing at the same time). I see the example with the form, but it would be nice to be able to interact with each item independently. We currently queue them up after each other.

Question: Migration from `flushbar`

I was previously using flushbar in my app and have now migrated however I am getting the following error:

_flushbarRoute@17117910' has not been initialized

My scenario is as follows:

// BLE devices connects
connectFlushbar = Flushbar(title: connectedName);
if (!connectFlushbar.isShowing()) {.          <-------- Error here
connectFlushbar.show(context);
}

When I was using flushbar the _flushbarRoute was null until it was shown however using another_flushbar it is not initialized which is why isShowing() creates the error. I am not really sure where to go from here. Any help would be appreciated.

Note: I have the check because multiple BLE devices can connect simultaneously (or close to it) and therefore I do not want to bombard the user with flushbars if this happens.

Problem to run the app, because of null check

Hi, we are facing difficult to iniatialize the because of one line or something relad the bus is:

/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/another_flushbar-1.10.29/lib/flushbar.dart:350:31: Error: Method 'addPostFrameCallback' cannot be called on 'SchedulerBinding?' because it is potentially null.

  • 'SchedulerBinding' is from 'package:flutter/src/scheduler/binding.dart' ('/C:/src/flutter/packages/flutter/lib/src/scheduler/binding.dart').
    package:flutter/…/scheduler/binding.dart:1
    Try calling using ?. instead.
    SchedulerBinding.instance.addPostFrameCallback(
    ^^^^^^^^^^^^^^^^^^^^

                            FAILURE: Build failed with an exception.
    
  • Where:
    Script 'C:\src\flutter\packages\flutter_tools\gradle\flutter.gradle' line: 1070

  • What went wrong:
    Execution failed for task ':app:compileFlutterBuildDebug'.

Process 'command 'C:\src\flutter\bin\flutter.bat'' finished with non-zero exit value 1

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

Unhandled Exception: Null check operator used on a null value

When trying to show a FlushbarHelper.createSuccess() flusher, it fails with the following error and trace stack:

Unhandled Exception: Null check operator used on a null value
#0 StatefulElement.state
package:flutter/…/widgets/framework.dart:4789
#1 Navigator.of
package:flutter/…/widgets/navigator.dart:2730
#2 Flushbar.show
package:another_flushbar/flushbar.dart:233
#3 _LoginState.build.
package:app/…/auth/login.dart:258

I am not sure why this is the case, and any help or advice would be great.

FlushbarHelper.createAction() "button" parameter takes a FlatButton which is now deprecated in favor of TextButton.

FlushbarHelper.createAction() "button" parameter takes a FlatButton which is now deprecated in favor of TextButton (at least on beta channel, so stable can't be far behind if not there already). This, of course, causes a deprecation warning.

This is just passed through to Flushbar ctor's "mainButton" parameter, which takes a Widget:

  /// Get a flushbar that can receive a user action through a button.
  static Flushbar createAction(
      {@required String message,
        @required FlatButton button, // deprecated
        String title,
        Duration duration = const Duration(seconds: 3)}) {
    return Flushbar(
      title: title,
      message: message,
      duration: duration,
      mainButton: button,
    );

This can be most easily and probably very safely corrected by doing what Flushbar itself does for mainButton, and accept a Widget:

  /// Get a flushbar that can receive a user action through a button.
  static Flushbar createAction(
      {@required String message,
        @required Widget button, // does the trick
        String title,
        Duration duration = const Duration(seconds: 3)}) {
    return Flushbar(
      title: title,
      message: message,
      duration: duration,
      mainButton: button,
    );

Shouldn't break any existing code, and has the advantage of offering the user more choice to pass what they want, like an ElevatedButton or an IconButton.

The documentation should also be amended to merely recommend TextButton for createAction.

BTW, StatelessWidget is the closest common ancestor for TextButton and FlatButton, so, might as well just go to Widget. Can't hurt.

Thanks for taking over flushbar! another_flushbar is much appreciated!

v1.10.12: generated_plugin_registrant.dart: Undefined name 'AnotherFlushbarPlugin'

Upgrading from 1.10.11 to 1.10.12 introduces this error in the Dart Analysis windows.
Compilation works though.

error: Undefined name 'AnotherFlushbarPlugin'. (undefined_identifier at [xyz] lib\generated_plugin_registrant.dart:21)
info: Unused import: 'package:another_flushbar/flushbar.dart'. (unused_import at [xyz] lib\generated_plugin_registrant.dart:7)

[Bug] Can't access widgets below Flushbar when margin is set

In my app I would like to have floating flushbar, with some padding on bottom - so I achieve this by setting margin in flushbar constructor.
However, items below flushbar do not respond to touch until it's dismissed - like if flushbar is covering them with some transparent Container.

It would be great if flushbar with bottom/top margin didn't make widgets below inaccessible.

black bar on app login

I have flushbar set up with a notification service so that I can display messages to the user asynchronously when background operations are complete on any screen they may be on. This works flawlessly and is no issue. However, when logging in to the app, a black bar displays at the bottom of the screen where the flush bar is set to display. This disappears after about 5 seconds or so but it still should not display. looking through the code I can see that the flushbar is supposed to be transparent on initialization, yet there it is. It does not display after the user has logged in (normal app launch where the user is already logged in). has anyone encountered this, and how did you resolve it?
Capture_annointed

isDissmissible doesnt work with "back" button.

I try to use isDissmissible=false, to turn off swiping dissmissible. I want to dissmiss flushbar manually by a condition (in code).
And now swiping doesnt dismiss the flushbar, but when I press the native android "back" button, the flushbar is dismissing.
How can I turn off all possible ways to dismiss except of manually call Flushbar().dismiss() ??

Build Fails

I have a dependency another_flushbar leading to following entry in the generated_plugin_registrant.dart file:

import 'package:another_flushbar/flushbar.dart';

void registerPlugins(Registrar registrar) {
  AnotherFlushbarPlugin.registerWith(registrar);
  registrar.registerMessageHandler();
}

The linter shows the error Undefined name 'AnotherFlushbarPlugin'. Try correcting the name to one that is defined, or defining the name. which is absolutely correct because the class referenced doesn't exist in the imported file.

When I try to build, I get following errors:

Launching lib/main.dart on sdk gphone x86 arm in debug mode...
Plugin project :location_web not found. Please update settings.gradle.

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:processDebugResources'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > Android resource linking failed
     /Users/tobiaswimmer/Documents/Development/fakks/consumer/build/location/intermediates/library_manifest/debug/AndroidManifest.xml:11:9-15:56: AAPT: error: attribute android:foregroundServiceType not found.


* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 8s
The build failed likely due to AndroidX incompatibilities in a plugin. The tool is about to try using Jetifier to solve the incompatibility.
Building plugin another_flushbar...

FAILURE: Build failed with an exception.

* What went wrong:
Task 'assembleAarRelease' not found in root project 'another_flushbar'.

* Try:
Run gradlew tasks to get a list of available tasks. Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 657ms
Exception: The plugin another_flushbar could not be built due to the issue above.
Exited (sigterm)

How can I fix this issue?

flushbar hides behind keyboard flutter

I have a simple form and always snackbar shows behind keyboard. Any special configuration so I can show my snackbar top of the keyboard in android and iOS. Any idea? Thanks

Fix side indictor when text is long

Hello

If I have a lot of text content in my flushbar, the left indicator will be short, here is a screenshot:
Screenshot_20210716-213248

Could you please fix that in any possible way?
Thank you

Flushbar Not Testable With duration

Minimal reproducable example:

Widget with flushbar:

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

class FlushbarExample extends StatelessWidget {
  const FlushbarExample({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      child: Text("Button"),
      onPressed: () {
        Flushbar(
          flushbarPosition: FlushbarPosition.BOTTOM,
          message: "Help",
          duration: const Duration(seconds: 3),
        ).show(context);
      },
    );
  }
}

Testclass:

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

import 'flush_example.dart';

main() {
  testWidgets(
    "test flushbar",
    (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Scaffold(
            body: FlushbarExample(),
          ),
        ),
      );
      var button = find.text("Button");
      expect(button, findsOneWidget);
      await tester.tap(button);
      await tester.pump(const Duration(seconds: 2));
      expect(find.text("Help"), findsOneWidget);
      await tester.pump(const Duration(seconds: 2));
    },
  );
}

Error

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following assertion was thrown running a test:
'package:flutter/src/widgets/navigator.dart': Failed assertion: line 5021 pos 12:
'entry.currentState == _RouteLifecycle.popping ||
          (entry.hasPage && entry.currentState.index < _RouteLifecycle.pop.index)': is not true.

Either the assertion indicates an error in the framework itself, or we should provide substantially
more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  [https://github.com/flutter/flutter/issues/new?template=2_bug.md]()

When the exception was thrown, this was the stack:
#2      NavigatorState.finalizeRoute (package:flutter/src/widgets/navigator.dart:5021:12)
#3      OverlayRoute.didPop (package:flutter/src/widgets/routes.dart:74:18)
#4      FlushbarRoute.didPop (package:another_flushbar/flushbar_route.dart:393:18)
#5      _RouteEntry.handlePop (package:flutter/src/widgets/navigator.dart:2896:16)
#6      NavigatorState._flushHistoryUpdates (package:flutter/src/widgets/navigator.dart:3860:22)
#7      NavigatorState.pop (package:flutter/src/widgets/navigator.dart:4902:7)
#8      FlushbarRoute._configureTimer.<anonymous closure> (package:another_flushbar/flushbar_route.dart:403:22)
#15     FakeTimer._fire (package:fake_async/fake_async.dart:316:16)
#16     FakeAsync._fireTimersWhile (package:fake_async/fake_async.dart:240:13)
#17     FakeAsync.elapse (package:fake_async/fake_async.dart:137:5)
#18     AutomatedTestWidgetsFlutterBinding.pump.<anonymous closure> (package:flutter_test/src/binding.dart:986:28)
#21     TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)
#22     AutomatedTestWidgetsFlutterBinding.pump (package:flutter_test/src/binding.dart:982:27)
#23     WidgetTester.pump.<anonymous closure> (package:flutter_test/src/widget_tester.dart:608:53)
#26     TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:71:41)
#27     WidgetTester.pump (package:flutter_test/src/widget_tester.dart:608:27)
#28     main.<anonymous closure> ([file:///C:/projects/flutter/trainingsmagnet/test/example/flush_example_test.dart:22:20]())
<asynchronous suspension>
<asynchronous suspension>
(elided 13 frames from class _AssertionError, dart:async, and package:stack_trace)

The test description was:
  test flushbar
════════════════════════════════════════════════════════════════════════════════════════════════════

Remove the Duration property in the widget and it works fine.

Class 'Future<dynamic>' has no instance method show

Hello I have the following problem, in my code I call the flushbar as follows:

onPressed: () => activeNotification ? setLetterGridState(index) : Flushbar(

and if the condition with

setLetterGridState(index)

is active, then the following error is displayed:

Performing hot reload...
Syncing files to device sdk gphone x86 arm...
Reloaded 1 of 1019 libraries in 532ms.

======== Exception caught by gesture ===============================================================
The following NoSuchMethodError was thrown while handling a gesture:
Class 'Future<dynamic>' has no instance method 'show'.
Receiver: Instance of 'Future<dynamic>'
Tried calling: show(Instance of 'SliverMultiBoxAdaptorElement')

When the exception was thrown, this was the stack: 
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:63:5)
#1      SettingsPageState.build.<anonymous closure>.<anonymous closure> (package:logo_dash/screens/settings.dart:496:30)
#2      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:989:21)
#3      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:193:24)
#4      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:608:11)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#d8ca8
  debugOwner: GestureDetector
  state: ready
  won arena
  finalPosition: Offset(208.8, 592.4)
  finalLocalPosition: Offset(27.2, 19.2)
  button: 1
  sent tap down
====================================================================================================

Despite the error, everything works as it should. How can I solve this so that this error doesn't come back?

iOS Flushbar does not stay grounded at bottom of screen, even with "FlushbarStyle.GROUNDED". There is blank space where the iOS dismiss bar is located.

iOS Flushbar does not stay grounded at bottom of screen, even with "FlushbarStyle.GROUNDED". There is blank space where the iOS dismiss bar is located. This only happens when I use "containers" as the widget instead of a Text widget.

NOTE: USING VERSION 1.10.11 BECAUSE WE ARE WAITING ON SOME OTHER PACKAGES TO BECOME NULL SAFE BEFORE UPGRADING OUR DART VERSION.

[Question/Bug] leftBarIndicatorColor and borderRadius

Describe the bug

When using leftBarIndicatorColor property alongside borderRadius, the left side doesn't respect the borderRadius property. Is it correct? If so, what about implementing an option to forceBorderRadius?

Paste relevant code

Flushbar(
      message: message,
      icon: const Icon(Icons.warning, color: Colors.red),
      leftBarIndicatorColor: Colors.red,
      duration: _defaultDuration,
      margin: _defaultMargin,
      borderRadius: _defaultBorderRadius,
    ).show(context);

Screenshots

image

FlushBar error on Flutter 2.10.2 'entry.currentState == _RouteLifecicle.popping......'

Flushbar is crashing on Flutter 2.10.+

Here is the log:

Failed assertion: line 5021 pos 12: 'entry.currentState == _RouteLifecycle.popping || (entry.hasPage && entry.currentState.index < _RouteLifecycle.pop.index)': is not true. flutter: #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:51:61) #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:40:5) #2 NavigatorState.finalizeRoute (package:flutter/src/widgets/navigator.dart:5021:12) #3 OverlayRoute.didPop (package:flutter/src/widgets/routes.dart:74:18) #4 FlushbarRoute.didPop (package:another_flushbar/flushbar_route.dart:393:18) #5 _RouteEntry.handlePop (package:flutter/src/widgets/navigator.dart:2896:16) #6 NavigatorState._flushHistoryUpdates (package:flutter/src/widgets/navigator.dart:3860:22) #7 NavigatorState.pop (package:flutter/src/widgets/navigator.dart:4902:7) #8 FlushbarRoute._configureTimer.<anonymous closure> (package:another_flushbar/flushbar_route.dart:403:22) #9 _rootRun (dart:async/zone.dart:1418:47) #10 _CustomZone.run (dart:async/zone.dart:1328:19) #11 _CustomZone.runGuarded (dart:async/zone.dart:1236:7) #12 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1276:23) #13 _rootRun (dart:async/zone.dart:1426:13) #14 _CustomZone.run (dart:async/zone.dart:1328:19) #15 _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1260:23) #16 Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15) #17 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:395:19) #18 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:426:5) #19 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)

Has Flushbar or not?

Hi everyone, how can I check if there already a Flushbar is? I don't want to show Flashbar above previous Flashbar. It's weird. Thanks in advance!
P.S. In regular SnackBar from Scaffold you can remove current SnackBar:)

StatusBar always overridden by SystemChrome

First of all, thank you for your work!
Setting the statusBarColor in main.dart for global usecase. But flushbar can't override the color.

SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(statusBarColor: Dark.dp01));
Flushbar<T>(
    flushbarPosition: FlushbarPosition.TOP,
    flushbarStyle: FlushbarStyle.GROUNDED,
  )..bar.show(context);

Screenshot_1629829954

Swiping back while flushbar is dismissing freezes swiping animation

Video:

LDQK8580.MP4

Steps to Reproduce:

iPhone only

  1. Go to next page.
  2. Show flushbar.
  3. Start swiping back and release while flushbar is dismissing.
  4. Swiping animation freezes.

Code:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flushbar Error',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Page'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => SecondPage(),
              ),
            );
          },
          child: Text(
            'Go to second page',
          ),
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Flushbar(
              title: "Hey Ninja",
              message:
                  "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
              duration: Duration(seconds: 3),
            )..show(context);
          },
          child: Text(
            'Show flushbar',
          ),
        ),
      ),
    );
  }
}

Application throws error

I believe, this happens, when a flushbar is dismissed, but I don't know for sure, because there is no line from my app code in the stack, so I'm actually a bit confused, what I could do to debug this:

======== Exception caught by foundation library ====================================================
The following _TypeError was thrown while dispatching notifications for OverlayEntry:
type 'Null' is not a subtype of type 'Object'

When the exception was thrown, this was the stack: 
#1      FlushbarRoute.dispose (package:another_flushbar/flushbar_route.dart:438:26)
#2      _RouteEntry.dispose.<anonymous closure> (package:flutter/src/widgets/navigator.dart:3001:19)
#3      ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:308:24)
#4      OverlayEntry._updateMounted (package:flutter/src/widgets/overlay.dart:130:5)
#5      _OverlayEntryWidgetState.dispose (package:flutter/src/widgets/overlay.dart:200:18)
#6      StatefulElement.unmount (package:flutter/src/widgets/framework.dart:4983:11)
#7      _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1926:13)
#8      ListIterable.forEach (dart:_internal/iterable.dart:39:13)
#9      _InactiveElements._unmountAll (package:flutter/src/widgets/framework.dart:1935:25)
#10     BuildOwner.lockState (package:flutter/src/widgets/framework.dart:2519:15)
#11     BuildOwner.finalizeTree (package:flutter/src/widgets/framework.dart:2932:7)
#12     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:884:19)
#13     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:363:5)
#14     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1144:15)
#15     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1081:9)
#16     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:995:5)
#20     _invoke (dart:ui/hooks.dart:151:10)
#21     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:308:5)
#22     _drawFrame (dart:ui/hooks.dart:115:31)
(elided 4 frames from dart:async)
The OverlayEntry sending notification was: OverlayEntry#a3e2b(opaque: false; maintainState: false)
====================================================================================================

I switched to another-flushbar to when I switched my code to null safety.
My environment is:

Flutter 2.10.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision db747aa133 (3 weeks ago) • 2022-02-09 13:57:35 -0600
Engine • revision ab46186b24
Tools • Dart 2.16.1 • DevTools 2.9.2

Any help in debugging this is highly welcome.
Not expecting anyone to actually look into my app, but just for reference, it is Encrateia and the state I'm talking about is in the upgrade-2021-project branch.

close before show new flusbar

Good day! I didnt find any method to programmatically close the current flushbar. There is a solution for snackbars (ScaffoldMessenger.of(context)..hideCurrentSnackbar()..showSnackbar(); .... how to implement this with flushbar?

Release upgrade to flutter 3 in a small version is a mistake

Hey, I'm using flutter_login in my project, and another_flushbar is one of the dependencies of flutter_login. Thx for your awesome work here.

I noticed that there is a release of 1.10.29 - 2022-17-05, that declares merged flutter v3.

With this change, my project (based on flutter v2.10.4) failed to build with the message:

../../../green_software/flutter/.pub-cache/hosted/pub.dartlang.org/another_flushbar-1.10.29/lib/flushbar.dart:350:31: Error: Method 'addPostFrameCallback' cannot be called on 'SchedulerBinding?' because it is potentially null.
 - 'SchedulerBinding' is from 'package:flutter/src/scheduler/binding.dart' ('../../../green_software/flutter/packages/flutter/lib/src/scheduler/binding.dart').
Try calling using ?. instead.
    SchedulerBinding.instance.addPostFrameCallback(
                              ^^^^^^^^^^^^^^^^^^^^
Failed to package /Users/mac/gitrepo/presence/Presence-FE.
Command PhaseScriptExecution failed with a nonzero exit code

I think this is because flutter_login writes dependency as another_flushbar: ^1.10.28, as 1.10.29 is released, flutter pub get will treat it as a compatible version of v1.10.28 and use the newer one, which is actually with huge change and may cause an unknown error.

So, I think it is not proper to release a function like merged flutter v3 in a small version.

I'm new to flutter, do you have any others suggestions on managing flutter dependencies so that I can avoid such a problem?

Many thanks to your contribution to the community again!

Disable changing web address when flushbars are shown

On web, when a flush bar is shown it forcibly changes the web route to /flushbarRoute. Once the flushbar is dismissed the address reverts to what it was previously.

This is problematic because if the user refreshes the page while the flush bar is active (or takes any other navigation action dependent on the web address), then the page the user was on is lost.

The ideal solution would be to optionally disable the flushbars from changing the web address.

Navigator.pop does not work

Common usage of classic snackbar is display snackbar and pop current page.

However when using Flushbar like this

ElevatedButton(
    child: Text('Show Flushbar and pop!'),
    onPressed: () {
      Flushbar(
        message: 'Pop!',
        onStatusChanged: print,
        duration: Duration(seconds: 4),
      )..show(context);
      Navigator.of(context).pop();
    },
  ),
 )

Nothing happens. No flushbar is displayed nor current page is popped.

When I try to listen for Flushbar's status changes, the states are

I/flutter (18959): FlushbarStatus.IS_APPEARING
I/flutter (18959): FlushbarStatus.DISMISSED

However when I remove Navigator.of(context).pop() line. The printed status is:

I/flutter (18959): FlushbarStatus.IS_APPEARING
I/flutter (18959): FlushbarStatus.SHOWING
I/flutter (18959): FlushbarStatus.IS_HIDING
I/flutter (18959): FlushbarStatus.DISMISSED

I think this should be considered as a bug. With normal Flutter's snackbar this is not issue.

Flushbar is hidden behind keyboard

When a Flushbar is shown while the keyboard is open the Flushbar is hidden behind it.
When I use a standard Snackbar instead it is shown above the keyboard.

My expectation is that the Flushbar is shown above the keyboard as well.

Same problem as
AndreHaueisen/flushbar#7

How to check if flushbar is already open?

I'd like to check if flushbar is already open before showing a new one. Otherwise, the new one overlaps the old one. Something like this:

if (!Flushbar.isFlushbarOpen) {
    // Show Flushbar...
}

Thanks in advance.

Get Flushbar Height

Is it possible to get the height of the Flushbar widget as shown in the UI and move other widget using that value instead of covering them?

Expected value of SkDeletable, but got one of type Null

Running release 1.10.11, after upgrading project to Flutter 2, I am seeing an error (on Flutter WEB only) whereby when a flushbar is showing when a route is pushed, I am encountering an error:

The following TypeErrorImpl was thrown building FutureBuilder(dirty, state: _FutureBuilderState#0334f):
Expected a value of type 'SkDeletable', but got one of type 'Null'

The relevant error-causing widget was: 
  Flushbar<dynamic> file:/// {project path to page} /login_page.dart:513:14
When the exception was thrown, this was the stack: 
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 236:49  throw_
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 84:3    castError
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart 266:34   as
C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/canvaskit/skia_object_cache.dart 146:55    new
C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/canvaskit/image_filter.dart 26:3           __

Gestures dont dismiss flushbar

The issue is the following:

I'm having a flushbar with blockBackgroundInteraction: true and isDismissible: true
tapping on the background dismisses the flushbar (as Indented)
other gestures, like starting a swipe etc, don't dismiss the flushbar (would be nice, to have the option)

How to reproduce:

  1. Build the following App
  2. Push the PLUS
  3. Swipe the screen (nothing happens)
  4. Tap the screen
  5. flushbar closes
import 'package:flutter/material.dart';

import 'package:another_flushbar/flushbar.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Hello flushbar:',
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          await Flushbar(
            title: 'Hey Ninja',
            message:
                'Lorem Ipsum is simply dummy text of the printing and typesetting industry',
            duration: Duration(seconds: 3),
            blockBackgroundInteraction: true,
          ).show(context);
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

Widget testing for Flushbar with duration

Hello, I try to create the widget test for the flushbar component (with duration). However, is seems there is timer that block the process like this:

Pending timers:
Timer (duration: 0:00:02.000000, periodic: false), created:
#0 new FakeTimer._ (package:fake_async/fake_async.dart:284:41)
#1 FakeAsync._createTimer (package:fake_async/fake_async.dart:248:27)
#2 FakeAsync.run. (package:fake_async/fake_async.dart:181:19)
#5 FlushbarRoute._configureTimer (package:another_flushbar/flushbar_route.dart:393:16)
#6 FlushbarRoute.didPush (package:another_flushbar/flushbar_route.dart:347:5)
#7 _RouteEntry.handlePush (package:flutter/src/widgets/navigator.dart:3013:46)
#8 NavigatorState._flushHistoryUpdates (package:flutter/src/widgets/navigator.dart:3958:17)
#9 NavigatorState._pushEntry (package:flutter/src/widgets/navigator.dart:4573:5)
#10 NavigatorState.push (package:flutter/src/widgets/navigator.dart:4480:5)
#11 Flushbar.show (package:another_flushbar/flushbar.dart:267:10)
#12 _RandomUserScreenState._buildGenerateButton. (package:feature_user/presentation/views/random_user_screen.dart:110:15)

(elided 2 frames from dart:async)

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following assertion was thrown running a test (but after the test had completed):
A Timer is still pending even after the widget tree was disposed.
'package:flutter_test/src/binding.dart':
Failed assertion: line 1245 pos 12: '!timersPending'

When the exception was thrown, this was the stack:
#2 AutomatedTestWidgetsFlutterBinding._verifyInvariants (package:flutter_test/src/binding.dart:1245:12)
#3 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:806:7)

(elided 2 frames from class _AssertionError)

Because of this, I can only expect the flushbar value just after the timer process done like this:

      // Duration of flushbar is 2 second
      await tester.pumpAndSettle(Duration(seconds: 2));
      final flushbarSuccess = find.text("Successfully added");
      expect(flushbarSuccess, findsOneWidget);

However, this will give the test result is failed because the flushbarSuccess already dismissed after 2 second. Is there any way to test the Flushbar?

Null Safety

It would be really cool if the package migrates to null safety in the next months :)

Flutter 3 Upgrade

Package is incompatible with Flutter 3's changes to null-aware operations.

../../Library/Flutter/flutter/.pub-cache/hosted/pub.dartlang.org/another_flushbar-1.10.28/lib/flushbar.dart:350:22: Warning: Operand of null-aware operation '!' has type 'SchedulerBinding' which excludes null.
[ ] - 'SchedulerBinding' is from 'package:flutter/src/scheduler/binding.dart' ('../../Library/Flutter/flutter/packages/flutter/lib/src/scheduler/binding.dart').
[ ] SchedulerBinding.instance!.addPostFrameCallback(

Background interaction is blocked bellow flushbar

Problem: Despite blockBackgroundInteraction is set to false, the area bellow the flushbar is blocked (area above is usable).
There is no difference, if the spacing to the bottom is defined via a margin or with positionOffset (uncommented in the package code).

Request: The area bellow the flushbar is interactable, so the user can still tap for example on a bottomNavigation, if a flushbar is shown (see following screenshot).
grafik

Throwing error stating cannot be called on 'SchedulerBinding?'

Error: Method 'addPostFrameCallback' cannot be called on 'SchedulerBinding?' because it is potentially null.

  • 'SchedulerBinding' is from 'package:flutter/src/scheduler/binding.dart' ('/C:/src/flutter/packages/flutter/lib/src/scheduler/binding.dart').
    Try calling using ?. instead.
    SchedulerBinding.instance.addPostFrameCallback(
    ^^^^^^^^^^^^^^^^^^^^

This error is only occurring when using version 1.10.28 or 1.10.29 but not in 1.10.27
In flushbar.dart line number 350.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.