toastification
toastification copied to clipboard
Exception on close toastification manually [Probably only in flutter web]
Describe the bug This error occurs when I hit the close button.
Screenshots
Flutter information:
- OS: [Windows]
- Flutter Version: [3.13.6]
- Toastification Version [1.0.1]
I have the same issue on the web, it looks like it only happens when the progress bar option is set to true.
https://github.com/payam-zahedi/toastification/assets/2213079/75f5a572-3818-47a8-9c79-b8b0bec93034
I couldn't find a solution for this.
Basically, I don't know how it is happening.
My guess is that it is related to Animated List
and it's a bug of the flutter.
I have the same issue on the web, it looks like it only happens when the progress bar option is set to true. Screen.Recording.2023-10-31.at.10.07.10.PM.mov
I could reproduce it even without progress bar
This is still an issue on flutter web.
Flutter 3.19.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 7482962148 (5 days ago) • 2024-02-27 16:51:22 -0500
Engine • revision 04817c99c9
Tools • Dart 3.3.0 • DevTools 2.31.1
any update ?
any update ? Right after the toast is dismissed from screen, the error will show
Flutter 3.16.9 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 41456452f2 (7 weeks ago) • 2024-01-25 10:06:23 -0800
Engine • revision f40e976bed
Tools • Dart 3.2.6 • DevTools 2.28.5
Wrap it with Future.delay:
Wrap it with Future.delay:
Does this work @Trung15010802 ?
Wrap it with Future.delay:
Does this work @Trung15010802 ?
It's work for me. I don't see any error
The problem is we don't have enough information to fix this
I'm not really sure what is the exact problem
Wrap it with Future.delay:
Does this work @Trung15010802 ?
It's work for me. I don't see any error
Thanks @Trung15010802. I've realized that addPostFrameCallback
also works.
WidgetsBinding.instance.addPostFrameCallback(() => toastification.show());
Turning off this code in the ToastificationManager class fixes the error but you lose the return animation.
// if (showRemoveAnimation) {
// _listGlobalKey.currentState?.removeItem(
// index,
// (BuildContext context, Animation
// if the [showRemoveAnimation] is false, we will remove the notification
// without showing the remove animation.
// } else {
// _listGlobalKey.currentState?.removeItem(
// index,
// (BuildContext context, Animation<double> animation) {
// return const SizedBox.shrink();
// },
// );
// }
Turning off this code in the ToastificationManager class fixes the error but you lose the return animation.
// if (showRemoveAnimation) { // _listGlobalKey.currentState?.removeItem( // index, // (BuildContext context, Animation animation) { // return ToastHolderWidget( // item: removedItem, // animation: animation, // alignment: alignment, // transformerBuilder: _toastAnimationBuilder(removedItem), // ); // }, // duration: _createAnimationDuration(removedItem), // );
// if the [showRemoveAnimation] is false, we will remove the notification // without showing the remove animation. // } else { // _listGlobalKey.currentState?.removeItem( // index, // (BuildContext context, Animation<double> animation) { // return const SizedBox.shrink(); // }, // ); // }
This is not the solution
This not make sense to disable the return animation
we should find the exact problem
Turning off this code in the ToastificationManager class fixes the error but you lose the return animation. // if (showRemoveAnimation) { // _listGlobalKey.currentState?.removeItem( // index, // (BuildContext context, Animation animation) { // return ToastHolderWidget( // item: removedItem, // animation: animation, // alignment: alignment, // transformerBuilder: _toastAnimationBuilder(removedItem), // ); // }, // duration: _createAnimationDuration(removedItem), // );
// if the [showRemoveAnimation] is false, we will remove the notification // without showing the remove animation. // } else { // _listGlobalKey.currentState?.removeItem( // index, // (BuildContext context, Animation<double> animation) { // return const SizedBox.shrink(); // }, // ); // }
This is not the solution
This not make sense to disable the return animation
we should find the exact problem
Yes, I agree, I offered a suggestion as a temporary solution. Now as an advanced stage //duration: _createAnimationDuration(removedItem), in the comment line eliminated the error. However, I could not understand exactly what _createAnimationDuration does as a function.
if (showRemoveAnimation) {
_listGlobalKey.currentState?.removeItem(
index,
(BuildContext context, Animation<double> animation) {
return ToastHolderWidget(
item: removedItem,
animation: animation,
alignment: alignment,
transformerBuilder: _toastAnimationBuilder(removedItem),
);
},
//duration: _createAnimationDuration(removedItem),
);
}
I have the same issue on the web, it looks like it only happens when the progress bar option is set to true. Screen.Recording.2023-10-31.at.10.07.10.PM.mov
I could reproduce it even without progress bar
Same :(
Wrap it with Future.delay:
Does this work @Trung15010802 ?
It's work for me. I don't see any error
Thanks @Trung15010802. I've realized that
addPostFrameCallback
also works.WidgetsBinding.instance.addPostFrameCallback(() => toastification.show());
Didn't work. Not did wrapping it in a Future(Duration.zero) :(
WidgetsBinding.instance.addPostFrameCallback((_) => toastification.show(
context: context,
type: ToastificationType.error,
style: ToastificationStyle.flatColored,
icon: const Icon(Icons.error_outline_rounded),
title: const Text('No Items Available'),
alignment: Alignment.topRight,
autoCloseDuration: const Duration(seconds: 4),
borderRadius: BorderRadius.circular(12.0),
applyBlurEffect: true,
));
This also did not work. The crash still happens:
Future.delayed(Duration.zero, () {
toastification.show(
context: context,
type: ToastificationType.error,
style: ToastificationStyle.flatColored,
icon: const Icon(Icons.error_outline_rounded),
title: const Text('No Items Available'),
alignment: Alignment.topRight,
autoCloseDuration: const Duration(seconds: 4),
borderRadius: BorderRadius.circular(12.0),
applyBlurEffect: true,
);
});
Error:
Error: AnimationController.dispose() called more than once. A given AnimationController cannot be disposed more than once. The following AnimationController object was disposed multiple times: AnimationController#d8f82(⏮ 0.000; paused; DISPOSED) dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 297:3 throw_ packages/flutter/src/animation/animation_controller.dart 823:9 <fn> packages/flutter/src/animation/animation_controller.dart 833:14 dispose packages/flutter/src/widgets/animated_scroll_view.dart 1198:55 <fn> dart-sdk/lib/async/zone.dart 1661:54 runUnary dart-sdk/lib/async/future_impl.dart 162:18 handleValue dart-sdk/lib/async/future_impl.dart 838:44 handleValueCallback dart-sdk/lib/async/future_impl.dart 867:13 _propagateToListeners dart-sdk/lib/async/future_impl.dart 643:5 [_completeWithValue] dart-sdk/lib/async/future_impl.dart 713:7 callback dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7 <fn>
Wrap it with Future.delay:
Does this work @Trung15010802 ?
It's work for me. I don't see any error
Thanks @Trung15010802. I've realized that
addPostFrameCallback
also works.WidgetsBinding.instance.addPostFrameCallback(() => toastification.show());
Didn't work. Not did wrapping it in a Future(Duration.zero) :(
WidgetsBinding.instance.addPostFrameCallback((_) => toastification.show( context: context, type: ToastificationType.error, style: ToastificationStyle.flatColored, icon: const Icon(Icons.error_outline_rounded), title: const Text('No Items Available'), alignment: Alignment.topRight, autoCloseDuration: const Duration(seconds: 4), borderRadius: BorderRadius.circular(12.0), applyBlurEffect: true, ));
This also did not work. The crash still happens:
Future.delayed(Duration.zero, () { toastification.show( context: context, type: ToastificationType.error, style: ToastificationStyle.flatColored, icon: const Icon(Icons.error_outline_rounded), title: const Text('No Items Available'), alignment: Alignment.topRight, autoCloseDuration: const Duration(seconds: 4), borderRadius: BorderRadius.circular(12.0), applyBlurEffect: true, ); });
Error:
Error: AnimationController.dispose() called more than once. A given AnimationController cannot be disposed more than once. The following AnimationController object was disposed multiple times: AnimationController#d8f82(⏮ 0.000; paused; DISPOSED) dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 297:3 throw_ packages/flutter/src/animation/animation_controller.dart 823:9 <fn> packages/flutter/src/animation/animation_controller.dart 833:14 dispose packages/flutter/src/widgets/animated_scroll_view.dart 1198:55 <fn> dart-sdk/lib/async/zone.dart 1661:54 runUnary dart-sdk/lib/async/future_impl.dart 162:18 handleValue dart-sdk/lib/async/future_impl.dart 838:44 handleValueCallback dart-sdk/lib/async/future_impl.dart 867:13 _propagateToListeners dart-sdk/lib/async/future_impl.dart 643:5 [_completeWithValue] dart-sdk/lib/async/future_impl.dart 713:7 callback dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7 <fn>
Yes, it's still have error but not much like before. I have switched to another packge
@payam-zahedi The issue is in the implementation of AnimatedList
, where dispose is called multiple times in different places. I fixied and now works without any exceptions. Until the fix is officially implemented, we can utilize the modified AnimatedList
. Here's the PR #102
@rebaz94 If the issue is really in AnimatedList, and you know what causes the problem, it would be nice if you create a reproducible code without toastification package, and open the issue on flutter repo
Wrap it with Future.delay:
It work for me, find my implementation below :
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:toastification/toastification.dart';
void createSuccessToast(BuildContext context,
{required String label,
String? description,
Duration? duration = const Duration(seconds: 5)}) =>
Future.delayed(
Duration.zero,
() => toastification.show(
context: context,
title: Text(label),
style: ToastificationStyle.flat,
autoCloseDuration: duration,
alignment: Alignment.topRight,
description: description != null
? RichText(text: TextSpan(text: description))
: null,
boxShadow: const [
BoxShadow(
color: Color(0x07000000),
blurRadius: 16,
offset: Offset(0, 16),
spreadRadius: 0,
)
],
type: ToastificationType.success));
showProgressBar: false, // this is probably what is fixing the issue
@rebaz94 If the issue is really in AnimatedList, and you know what causes the problem, it would be nice if you create a reproducible code without toastification package, and open the issue on flutter repo
We already have one issue for this on flutter repo
@rebaz94 If the issue is really in AnimatedList, and you know what causes the problem, it would be nice if you create a reproducible code without toastification package, and open the issue on flutter repo
Sorry, I'm unable to reproduce the bug without the toastification package.
@rebaz94 If the issue is really in AnimatedList, and you know what causes the problem, it would be nice if you create a reproducible code without toastification package, and open the issue on flutter repo
Sorry, I'm unable to reproduce the bug without the toastification package.
did you used state full widget?
No, the content of toast is just a Text
the problem is when we are using the showProgress
in that situation we are using a state full widget for our toasts otherwise we are using stateless widgets
and the problem is happening only with statefull widget
I see this error on auto close as well (but only once)
Error
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 296:3 throw_
errors.dart:296
packages/flutter/src/animation/animation_controller.dart 866:9 <fn>
animation_controller.dart:866
packages/flutter/src/animation/animation_controller.dart 876:14 dispose
animation_controller.dart:876
packages/flutter/src/widgets/animated_scroll_view.dart 1393:55 <fn>
animated_scroll_view.dart:1393
dart-sdk/lib/async/zone.dart 1661:54 runUnary
zone.dart:1661
dart-sdk/lib/async/future_impl.dart 163:18 handleValue
future_impl.dart:163
dart-sdk/lib/async/future_impl.dart 861:44 handleValueCallback
future_impl.dart:861
dart-sdk/lib/async/future_impl.dart 890:13 _propagateToListeners
future_impl.dart:890
dart-sdk/lib/async/future_impl.dart 666:5 [_completeWithValue]
future_impl.dart:666
dart-sdk/lib/async/future_impl.dart 736:7 callback
future_impl.dart:736
dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop
schedule_microtask.dart:40
dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop
schedule_microtask.dart:49
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7 <fn>
The issue is triggered by removing the overlay with the (not really) empty AnimatedList.
https://github.com/payam-zahedi/toastification/blob/423dae7520bf8a4ea10d48e90deeb96781ce1685/lib/src/core/toastification_manager.dart#L143-L153
When I disable the overlay removal or postpone it a little with (removedItem.animationDuration ?? config.animationDuration) + Durations.medium1
, the exception no longer occurs.
Is it necessary to remove the overlay every time the AnimatedList is empty?
@karelklic, you might be right.
It seems that the overlay could be moving off-screen just before the last toast animation completes.
Is it necessary to remove the overlay every time the AnimatedList is empty?
To address this, I think we need to remove the overlay, as it may display a hidden widget over the navigator widget.
Let's try increasing the duration and see if that resolves the issue.
Do you plan to open a PR for this? If so, I would appreciate it.