{"id":13465504,"url":"https://github.com/AndreHaueisen/flushbar","last_synced_at":"2025-03-25T16:31:55.689Z","repository":{"id":37444178,"uuid":"134632253","full_name":"AndreHaueisen/flushbar","owner":"AndreHaueisen","description":"Custom widget for Flutter","archived":false,"fork":false,"pushed_at":"2023-05-30T06:42:03.000Z","size":1318,"stargazers_count":1007,"open_issues_count":55,"forks_count":173,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-10-15T10:42:40.505Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AndreHaueisen.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-05-23T22:32:20.000Z","updated_at":"2024-10-12T17:52:56.000Z","dependencies_parsed_at":"2023-10-20T17:08:43.532Z","dependency_job_id":"079f33ee-c4e5-4bfa-a312-8a465b7d86d8","html_url":"https://github.com/AndreHaueisen/flushbar","commit_stats":{"total_commits":77,"total_committers":8,"mean_commits":9.625,"dds":0.1428571428571429,"last_synced_commit":"a259aad4c5abdd1a905ccefb6f78a838062d7168"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreHaueisen%2Fflushbar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreHaueisen%2Fflushbar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreHaueisen%2Fflushbar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreHaueisen%2Fflushbar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AndreHaueisen","download_url":"https://codeload.github.com/AndreHaueisen/flushbar/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222074960,"owners_count":16926640,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T15:00:31.319Z","updated_at":"2024-10-29T17:31:02.653Z","avatar_url":"https://github.com/AndreHaueisen.png","language":"Dart","funding_links":["https://www.buymeacoffee.com/AndreHaueisen"],"categories":["Components","Dart","组件","UI [🔝](#readme)","Flutter"],"sub_categories":["UI","Components"],"readme":"# Flushbar\n\nUse this package if you need more customization when notifying your user. For Android developers, it is made to substitute\ntoasts and snackbars. IOS developers, I don't know what you use there, but you will like it.\n\nSee the [install instructions](https://pub.dartlang.org/packages/flushbar#-installing-tab-).\n\n## Quick reference\n\nSince customization requires a lot of properties, here is a quick cheatsheet:\n\nProperty | What does it do\n-------- | ---------------\ntitle    | The title displayed to the user\nmessage  | The message displayed to the user.\ntitleText | Replaces [title]. Although this accepts a [widget], **it is meant to receive [Text] or [RichText]**\nmessageText | Replaces [message]. Although this accepts a [widget], **it is meant to receive [Text] or  [RichText]**\nicon | 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\nshouldIconPulse | An option to animate the icon (if present). Defaults to true.\nmaxWidth | Used to limit Flushbar width (usually on large screens)\nmargin | Adds a custom margin to Flushbar\npadding | Adds a custom padding to Flushbar. The default follows material design guide line\nborderRadius | Adds a radius to all corners of Flushbar. Best combined with [margin]. I do not recommend using it with [showProgressIndicator] or [leftBarIndicatorColor]\nborderColor | Adds a border to every side of Flushbar. I do not recommend using it with [showProgressIndicator] or [leftBarIndicatorColor]\nborderWidth | Changes the width of the border if [borderColor] is specified\nbackgroundColor | Flushbar background color. Will be ignored if [backgroundGradient] is not null.\nleftBarIndicatorColor | 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].\nboxShadows | 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](https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/shadows.dart)\nbackgroundGradient | Flushbar background gradient. Makes [backgroundColor] be ignored.\nmainButton | Use if you need an action from the user. [FlatButton] is recommended here.\nonTap | A callback that registers the user's click anywhere. An alternative to [mainButton]\nduration | How long until Flushbar will hide itself (be dismissed). To make it indefinite, leave it null.\nisDismissible | Determines if the user can swipe or click the overlay (if [routeBlur] \u003e 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.\ndismissDirection | FlushbarDismissDirection.VERTICAL by default. Can also be [FlushbarDismissDirection.HORIZONTAL] in which case both left and right dismiss are allowed.\nflushbarPosition | Flushbar can be based on [FlushbarPosition.TOP] or on [FlushbarPosition.BOTTOM] of your screen. [FlushbarPosition.BOTTOM] is the default.\nflushbarStyle | 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\nforwardAnimationCurve | The [Curve] animation used when show() is called. [Curves.easeOut] is default.\nreverseAnimationCurve | The [Curve] animation used when dismiss() is called. [Curves.fastOutSlowIn] is default.\nanimationDuration | Use it to speed up or slow down the animation duration\nshowProgressIndicator | true if you want to show a [LinearProgressIndicator]. If [progressIndicatorController] is null, an infinite progress indicator will be shown\nprogressIndicatorController | An optional [AnimationController] when you want to control the progress of your [LinearProgressIndicator]. You are responsible for controlling the progress\nprogressIndicatorBackgroundColor | a [LinearProgressIndicator] configuration parameter.\nprogressIndicatorValueColor | a [LinearProgressIndicator] configuration parameter.\nbarBlur | 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.\nblockBackgroundInteraction | Determines if user can interact with the screen behind it. If this is false, [routeBlur] and [routeColor] will be ignored\nrouteBlur | 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\nrouteColor | Default is [Colors.transparent]. Only takes effect if [routeBlur] \u003e 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\nuserInputForm | A [TextFormField] in case you want a simple user input. Every other widget is ignored if this is not null.\nonStatusChanged | a callback for you to listen to the different Flushbar status\n\n#### Quick tip\n\nIf you use a lot of those properties, it makes sense to make a factory to help with  your Flushbar's base appearance.\nThings 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.\n\n## We are on YouTube!\n\nWhile studying Flutter I stumbled on two amazing tutorials on how to use Flushbar.\nMake sure you show those guys some love.\n1. A beginners [tutorial](https://www.youtube.com/watch?v=KNpxyyA8MDA) by **Matej Rešetár**\n2. A more [advanced usage](https://www.youtube.com/watch?v=FRCvqkyeCzQ) by **Javier González Rodríguez**\n\n## Getting Started\n\nThe examples bellow were updated for version 1.3.0. Changes might have been made. See the [changelog](CHANGELOG.md) if any of the examples do not\nreflect Flushbar's current state.\n\n### The possibilities\n\n![Flushbar Animated](readme_resources/flushbar_animated.gif)\n\n### A basic Flushbar\n\nThe most basic Flushbar uses only a message. Failing to provide it before you call `show()` will result in a runtime error.\n`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`).\n\n- Note that only `message` is a required parameter. All the other ones are optional\n\n```dart\nclass YourAwesomeApp extends StatelessWidget {\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      title: 'YourAwesomeApp',\n      home: Scaffold(\n        Container(\n          child: Center(\n            child: MaterialButton(\n              onPressed: (){\n                Flushbar(\n                  title:  \"Hey Ninja\",\n                  message:  \"Lorem Ipsum is simply dummy text of the printing and typesetting industry\",\n                  duration:  Duration(seconds: 3),              \n                )..show(context);\n              },\n            ),\n          ),\n        ),\n      ),\n    );\n  }\n}\n```\n\n![Basic Example](readme_resources/basic_bar.png)\n\n### Lets get crazy Flushbar\n\nHere is how customized things can get.\n\n```dart\nFlushbar(\n      title: \"Hey Ninja\",\n      message: \"Lorem Ipsum is simply dummy text of the printing and typesetting industry\",\n      flushbarPosition: FlushbarPosition.TOP,\n      flushbarStyle: FlushbarStyle.FLOATING,\n      reverseAnimationCurve: Curves.decelerate,\n      forwardAnimationCurve: Curves.elasticOut,\n      backgroundColor: Colors.red,\n      boxShadows: [BoxShadow(color: Colors.blue[800], offset: Offset(0.0, 2.0), blurRadius: 3.0)],\n      backgroundGradient: LinearGradient(colors: [Colors.blueGrey, Colors.black]),\n      isDismissible: false,\n      duration: Duration(seconds: 4),\n      icon: Icon(\n        Icons.check,\n        color: Colors.greenAccent,\n      ),\n      mainButton: FlatButton(\n        onPressed: () {},\n        child: Text(\n          \"CLAP\",\n          style: TextStyle(color: Colors.amber),\n        ),\n      ),\n      showProgressIndicator: true,\n      progressIndicatorBackgroundColor: Colors.blueGrey,\n      titleText: Text(\n        \"Hello Hero\",\n        style: TextStyle(\n            fontWeight: FontWeight.bold, fontSize: 20.0, color: Colors.yellow[600], fontFamily: \"ShadowsIntoLightTwo\"),\n      ),\n      messageText: Text(\n        \"You killed that giant monster in the city. Congratulations!\",\n        style: TextStyle(fontSize: 18.0, color: Colors.green, fontFamily: \"ShadowsIntoLightTwo\"),\n      ),\n    );\n```\n\n![Complete Example](readme_resources/complete_bar.png)\n\n- Don't forget to call `show()` or the bar will stay hidden.\n- To deactivate any of those properties, pass `null` to it.\n\n### Styles\nFlushbar can be either floating or grounded to the edge of the screen.\nI don't recommend using `margin` or `borderRadius` if you chose `FlushbarStyle.GROUNDED` style.\n\n```dart\nFlushbar(flushbarStyle: FlushbarStyle.FLOATING)\n```\nor\n```dart\nFlushbar(flushbarStyle: FlushbarStyle.GROUNDED)\n```\nFloating Style            |  Grounded Style\n:------------------------------------------------------:|:-------------------------------------------------------:\n![Floating Style](readme_resources/floating_style.png)  |  ![Grounded Style](readme_resources/grounded_style.png) \n\n### Padding and Border Radius\nYou can give it some padding and a border radius. Works best with `FlushbarStyle.FLOATING`\n\n```dart\nFlushbar(\n  margin: EdgeInsets.all(8),\n  borderRadius: 8,\n);\n  \n```\n![Padding and Radius](readme_resources/padding_and_radius.png)\n\n### Left indicator bar\n\nFlushbar has a lateral bar to better convey the humor of the notification. To use it, simple give `leftBarIndicatorColor` a color.\n\n```dart\nFlushbar(\n  message: \"Lorem Ipsum is simply dummy text of the printing and typesetting industry\",\n  icon: Icon(\n    Icons.info_outline,\n    size: 28.0,\n    color: Colors.blue[300],\n    ),\n  duration: Duration(seconds: 3),\n  leftBarIndicatorColor: Colors.blue[300],\n)..show(context);\n```\n\n![Left indicator example](readme_resources/left_bar_indicator.png)\n\n### Customize your text\n\nIf you need a more fancy text, you can use [Text](https://docs.flutter.io/flutter/widgets/Text-class.html) or [RichText](https://api.flutter.dev/flutter/widgets/RichText-class.html)\nand pass it to the `titleText` or `messageText` variables.\n\n- Note that `title` will be ignored if `titleText` is not `null`\n- Note that `message` will be ignored if `messageText` is not `null`\n\n```dart\nFlushbar(\n  title: \"Hey Ninja\", //ignored since titleText != null\n  message: \"Lorem Ipsum is simply dummy text of the printing and typesetting industry\", //ignored since messageText != null\n  titleText: Text(\"Hello Hero\", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0 color: Colors.yellow[600], fontFamily:\"ShadowsIntoLightTwo\"),),\n  messageText: Text(\"You killed that giant monster in the city. Congratulations!\", style: TextStyle(fontSize: 16.0, color: Colors.green[fontFamily: \"ShadowsIntoLightTwo\"),),\n)..show(context);\n```\n\n![Customized Text](readme_resources/text_bar.png)\n\n### Customize background and shadow\n\nYou can paint the background with any color you want. You can use any shadow you want.\nJust give it a `backgroundColor` and `boxShadows`.\n\n```dart\nFlushbar(\n  title: \"Hey Ninja\",\n  message: \"Lorem Ipsum is simply dummy text of the printing and typesetting industry\",\n  backgroundColor: Colors.red,\n  boxShadows: [BoxShadow(color: Colors.red[800], offset: Offset(0.0, 2.0), blurRadius: 3.0,)],\n)..show(context);\n```\n\n![Background and Shadow](readme_resources/background_color_bar.png)\n\nWant a gradient in the background? No problem.\n\n- Note that `backgroundColor` will be ignored while `backgroundGradient` is not `null`\n\n```dart\nFlushbar(\n  title: \"Hey Ninja\",\n  message: \"Lorem Ipsum is simply dummy text of the printing and typesetting industry\",\n  backgroundGradient: LinearGradient(colors: [Colors.blue, Colors.teal]),\n  backgroundColor: Colors.red,\n  boxShadows: [BoxShadow(color: Colors.blue[800], offset: Offset(0.0, 2.0), blurRadius: 3.0,)],\n)..show(context);\n```\n\n![Background Gradient](readme_resources/gradient_bar.png)\n\n### Icon and button action\n\nLet us put a Icon that has a `PulseAnimation`. Icons have this animation by default and cannot be changed as of now.\nAlso, let us put a button. Have you noticed that `show()` returns a `Future`?\nThis Future will yield a value when you call `dismiss([T result])`.\nI recommend that you specify the `result` generic type if you intend to collect an user input.\n\n```dart\nFlushbar flush;\nbool _wasButtonClicked;\n```\n\n```dart\n@override\n  Widget build(BuildContext context) {\n    return Container(\n      child: Center(\n        child: MaterialButton(\n          onPressed: () {\n            flush = Flushbar\u003cbool\u003e(\n              title: \"Hey Ninja\",\n              message: \"Lorem Ipsum is simply dummy text of the printing and typesetting industry\",\n              icon: Icon(\n                       Icons.info_outline,\n                       color: Colors.blue,),\n              mainButton: FlatButton(\n                             onPressed: () {\n                                 flush.dismiss(true); // result = true\n                               },\n                             child: Text(\n                               \"ADD\",\n                               style: TextStyle(color: Colors.amber),\n                             ),\n                           ),) // \u003cbool\u003e is the type of the result passed to dismiss() and collected by show().then((result){})\n              ..show(context).then((result) {\n                setState(() { // setState() is optional here\n                  _wasButtonClicked = result;\n                });\n              });\n          },\n        ),\n      ),\n    );\n  }\n```\n\n![Icon and Button](readme_resources/icon_and_button_bar.png)\n\n### Flushbar position\n\nFlushbar can be at `FlushbarPosition.BOTTOM` or `FlushbarPosition.TOP`.\n\n```dart\nFlushbar(\n  flushbarPosition: FlushbarPosition.TOP,\n  title: \"Hey Ninja\",\n  message: \"Lorem Ipsum is simply dummy text of the printing and typesetting industry\",)..show(context);\n```\n\n![Bar position](readme_resources/position_bar.png)\n\n### Duration and dismiss policy\n\nBy default, Flushbar is infinite. To set a duration, use the `duration` property.\nBy default, Flushbar is dismissible by the user. A right or left drag will dismiss it.\nSet `isDismissible` to `false` to change this behaviour.\n\n```dart\nFlushbar(\n  title: \"Hey Ninja\",\n  message: \"Lorem Ipsum is simply dummy text of the printing and typesetting industry\",\n  duration: Duration(seconds: 3),\n  isDismissible: false,\n)..show(context);\n```\n\n### Progress Indicator\n\nIf you are loading something, use a [LinearProgressIndicator](https://docs.flutter.io/flutter/material/LinearProgressIndicator-class.html)\nIf you want an undetermined progress indicator, do not set `progressIndicatorController`.\nIf you want a determined progress indicator, you now have full control over the progress since you own the `AnimationController`\n\n- 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()`\n\n```dart\n\nAnimationController _controller = AnimationController(\n      vsync: this,\n      duration: Duration(seconds: 3),\n    );\n\nFlushbar(\n  title: \"Hey Ninja\",\n  message: \"Lorem Ipsum is simply dummy text of the printing and typesetting industry\",\n  showProgressIndicator: true,\n  progressIndicatorController: _controller,\n  progressIndicatorBackgroundColor: Colors.grey[800],\n)..show(context);\n```\n\n### Show and dismiss animation curves\n\nYou can set custom animation curves using `forwardAnimationCurve` and `reverseAnimationCurve`.\n\n```dart\nFlushbar(\n  forwardAnimationCurve: Curves.decelerate,\n  reverseAnimationCurve: Curves.easeOut,\n  title: \"Hey Ninja\",\n  message: \"Lorem Ipsum is simply dummy text of the printing and typesetting industry\",\n)..show(context);\n```\n\n### Listen to status updates\n\nYou can listen to status update using the `onStatusChanged` property.\n\n- 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.\n\n```dart\n\nFlushbar flushbar = Flushbar(title: \"Hey Ninja\", message: \"Lorem Ipsum is simply dummy text of the printing and typesetting industry\");\n\n  flushbar\n    ..onStatusChanged = (FlushbarStatus status) {\n      switch (status) {\n        case FlushbarStatus.SHOWING:\n          {\n            doSomething();\n            break;\n          }\n        case FlushbarStatus.IS_APPEARING:\n          {\n            doSomethingElse();\n            break;\n          }\n        case FlushbarStatus.IS_HIDING:\n          {\n            doSomethingElse();\n            break;\n          }\n        case FlushbarStatus.DISMISSED:\n          {\n            doSomethingElse();\n            break;\n          }\n      }\n    }\n    ..show(context);\n\n```\n\n### Input text\n\nSometimes we just want a simple user input. Use the property`userInputForm`.\n\n- Note that buttons, messages, and icons will be ignored if `userInputForm != null`\n- `dismiss(result)` will yield result. `dismiss()` will yield null.\n\n```dart\nFlushbar\u003cList\u003cString\u003e\u003e flush;\nfinal GlobalKey\u003cFormState\u003e _formKey = GlobalKey\u003cFormState\u003e();\n```\n\n```dart\nTextFormField getFormField(String text) {\n    return TextFormField(\n      initialValue: text,\n      style: TextStyle(color: Colors.white),\n      maxLength: 100,\n      maxLines: 1,\n      maxLengthEnforced: true,\n      decoration: InputDecoration(\n          fillColor: Colors.white10,\n          filled: true,\n          icon: Icon(\n            Icons.label,\n            color: Colors.grey[500],\n          ),\n          border: UnderlineInputBorder(),\n          helperText: \"Helper Text\",\n          helperStyle: TextStyle(color: Colors.grey),\n          labelText: \"Label Text\",\n          labelStyle: TextStyle(color: Colors.grey)),\n    );\n  }\n\nflush = Flushbar\u003cList\u003cString\u003e\u003e(\n  userInputForm = Form(\n          key: _formKey,\n          child: Column(\n            mainAxisSize: MainAxisSize.min,\n            children: [\n              getTextFormField(\"Initial Value\"),\n              getTextFormField(\"Initial Value Two\"),\n            ]\n            Align(\n              alignment: Alignment.bottomRight,\n              child: Padding(\n                padding: const EdgeInsets.only(top: 8.0),\n                child: MaterialButton(\n                  textColor: Colors.amberAccent,\n                  child: Text(\"SUBMIT\"),\n                  onPressed: () {\n                    flush.dismiss([_controller1.value.text, _controller2.value.text]);\n                  },\n                ),\n              ),\n            )\n          ],),),\n)..show(context).then((result) {\n        if (result != null) {\n          String userInput1 = result[0];\n          String userInput2 = result[1];\n        }\n      });\n```\n\nThis example tries to mimic the [Material Design style guide](https://material.io/design/components/text-fields.html#anatomy)\n\n![Bar input](readme_resources/input_bar.png)\n\n## Flushbar Helper\n\nI made a helper class to facilitate the creation of the most common Flushbars.\n\n```dart\nFlushbarHelper.createSuccess({message, title, duration});\nFlushbarHelper.createInformation({message, title, duration});\nFlushbarHelper.createError({message, title, duration});\nFlushbarHelper.createAction({message, title, duration flatButton});\nFlushbarHelper.createLoading({message,linearProgressIndicator, title, duration, progressIndicatorController, progressIndicatorBackgroundColor});\nFlushbarHelper.createInputFlushbar({textForm});\n```\n\n## Make it rain\n\n\u003ca href=\"https://www.buymeacoffee.com/AndreHaueisen\" target=\"_blank\"\u003e\u003cimg src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy Me A Coffee\" style=\"height: auto !important;width: auto !important;\" \u003e\u003c/a\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAndreHaueisen%2Fflushbar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAndreHaueisen%2Fflushbar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAndreHaueisen%2Fflushbar/lists"}