showEnhancedWidget static method

CancelFunc showEnhancedWidget({
  1. required ToastBuilder toastBuilder,
  2. UniqueKey? key,
  3. String? groupKey,
  4. Object crossPage = nil,
  5. Object allowClick = nil,
  6. Object clickClose = nil,
  7. Object ignoreContentClick = nil,
  8. Object onlyOne = nil,
  9. Object enableKeyboardSafeArea = nil,
  10. BackButtonBehavior? backButtonBehavior = nilBackButtonBehavior,
  11. FutureFunc? closeFunc = nilFutureFunc,
  12. VoidCallback? onClose = nilVoidCallback,
  13. Color backgroundColor = nilColor,
  14. WrapWidget? warpWidget = nilWrapWidget,
  15. Duration? duration = nilDuration,
})

Displays an enhanced Toast with many built-in features such as automatic timing closure, auto-closure on screen tap, and closure upon leaving the current Route. Core method, for detailed usage, refer to: BotToast.showAnimationWidget

toastBuilder is the builder function to generate the Widget to be displayed.

key represents a credential for this Toast. With this key, you can remove the Widget defined by the current key using remove.

groupKey represents a group key, mainly used for removeAll and remove.

crossPage displays across pages. If true, this Toast will appear across multiple Routes. If false, it will automatically close when the current Route changes, for example, Navigator.push - Navigator.pop.

allowClick determines whether normal clicking to trigger events is allowed while this Toast is displayed.

clickClose determines whether the Toast should automatically close when the screen is tapped to trigger an event.

ignoreContentClick determines whether to ignore the ToastContext area. When this parameter is true, user clicks within the ToastContext area will be able to reach the Page normally, in other words, it's transparent (even if the Toast background color is not transparent). If false, it behaves the opposite way.

onlyOne indicates whether only one Toast should exist within the same group at the same time. Groups are distinguished by groupKey.

closeFunc is a function mainly intended to perform actions before closing the Toast, such as triggering AnimationController to start and waiting for the animation to complete before closing.

backgroundColor is the background color of the MainContent area.

wrapWidget is a wrapping function that can be used to wrap the MainContent area. For example, showCustomLoading wraps an animation to give the MainContent area animation.

duration is the duration of the Toast. If null, it won't close automatically. If not null, it will automatically close after the specified time.

onClose is called when the Toast is closed.

enableKeyboardSafeArea determines whether to enable the keyboard safe area to prevent the keyboard from covering the Toast.

backButtonBehavior defines the behavior when the physical back button (on Android or equivalent) is pressed. Note that this is not the back button on the navigation bar. If ignore, it intercepts the back event. If close, it closes the toast and intercepts the event, stopping it from propagating. If null or none, it doesn't intercept the event.

显示一个增强Toast,该方法可以让Toast自带很多特性,例如定时关闭,点击屏幕自动关闭,离开当前Route关闭等等 核心方法,详情使用请看: BotToast.showAnimationWidget

toastBuilder 生成需要显示的Widget的builder函数

key 代表此Toast的一个凭证,凭此key可以删除当前key所定义的Widget,remove

groupKey 代表分组的key,主要用于removeAllremove

crossPage 跨页面显示,如果为true,则该Toast会跨越多个Route显示, 如果为false则在当前Route发生变化时,会自动关闭该Toast,例如Navigator.push-Navigator.pop

allowClick 是否在该Toast显示时,能否正常点击触发事件

clickClose 是否在点击屏幕触发事件时自动关闭该Toast

ignoreContentClick 是否忽视ToastContext区域 这个参数如果为true时,用户点击该ToastContext区域时,用户可以的点击事件可以正常到达到Page上 换一句话说就是透明的(即便是Toast背景颜色不是透明),如果为false,则情况反之

onlyOne 表示是否该分组内是否在同一时间里只存在一个Toast,区分是哪一个组是按照groupKey来区分的

closeFunc 该函数参数主要目的使Toast关闭之做一些处理例如 触发关闭前调用AnimationController来启动并等待动画后再关闭

backgroundColor MainContent区域的背景颜色

warpWidget 一个wrap函数,可以用来warp MainContent区域,例如showCustomLoading就包裹了一个动画 让MainContent区域也具有动画

duration 持续时间,如果为null则不会去定时关闭,如果不为null则在到达指定时间时自动关闭

onClose Toast关闭时调用

enableKeyboardSafeArea 是否启用键盘安全区,防止键盘挡住Toast

backButtonBehavior 点击物理返回键的行为(在android上等同于物理的返回键),注意不是导航条上的返回按钮 如果为ignore则拦截返回事件, 如果为close则关闭该toast,并且拦截事件停止冒泡 如果为null or none则不拦截事件

Implementation

static CancelFunc showEnhancedWidget({
  required ToastBuilder toastBuilder,
  UniqueKey? key,
  String? groupKey,
  /*bool*/ Object crossPage = nil,
  /*bool*/ Object allowClick = nil,
  /*bool*/ Object clickClose = nil,
  /*bool*/ Object ignoreContentClick = nil,
  /*bool*/ Object onlyOne = nil,
  /*bool*/ Object enableKeyboardSafeArea = nil,
  BackButtonBehavior? backButtonBehavior = nilBackButtonBehavior,
  FutureFunc? closeFunc = nilFutureFunc,
  VoidCallback? onClose = nilVoidCallback,
  Color backgroundColor = nilColor,
  WrapWidget? warpWidget = nilWrapWidget,
  Duration? duration = nilDuration,
}) {
  // ignore: unnecessary_null_comparison
  assert(enableKeyboardSafeArea != null);

  var o = defaultOption.enhanced;

  crossPage = returnFirstIfNotNil(crossPage, o.crossPage);
  allowClick = returnFirstIfNotNil(allowClick, o.allowClick);
  clickClose = returnFirstIfNotNil(clickClose, o.clickClose);
  ignoreContentClick = returnFirstIfNotNil(ignoreContentClick, o.ignoreContentClick);
  onlyOne = returnFirstIfNotNil(onlyOne, o.onlyOne);
  enableKeyboardSafeArea = returnFirstIfNotNil(enableKeyboardSafeArea, o.enableKeyboardSafeArea);
  backButtonBehavior = returnFirstIfNotNil(backButtonBehavior, o.backButtonBehavior);
  closeFunc = returnFirstIfNotNil(closeFunc, o.closeFunc);
  onClose = returnFirstIfNotNil(onClose, o.onClose);
  backgroundColor = returnFirstIfNotNil(backgroundColor, o.backgroundColor);
  warpWidget = returnFirstIfNotNil(warpWidget, o.warpWidget);
  duration = returnFirstIfNotNil(duration, o.duration);

  assert(isNilOr<bool>([enableKeyboardSafeArea, onlyOne, clickClose, allowClick, ignoreContentClick, crossPage]), 'Must be of bool type');

  //由于cancelFunc一开始是为空的,所以在赋值之前需要在闭包里使用
  late final CancelFunc cancelFunc;
  final CancelFunc dismissFunc = () async {
    await closeFunc?.call();
    cancelFunc();
  };

  //onlyOne 功能
  final List<CancelFunc> cache = (cacheCancelFunc[groupKey ?? defaultKey] ??= []);
  if (onlyOne == true) {
    final clone = cache.toList();
    cache.clear();
    clone.forEach((cancel) {
      cancel();
    });
  }
  cache.add(dismissFunc);

  //定时功能
  Timer? timer;
  if (duration != null) {
    timer = Timer(duration, () {
      dismissFunc();
      timer = null;
    });
  }

  //跨页自动关闭
  BotToastNavigatorObserverProxy? observerProxy;
  if (!(crossPage == true)) {
    observerProxy = BotToastNavigatorObserverProxy.all(dismissFunc);
    BotToastNavigatorObserver.register(observerProxy);
  }

  //拦截点击返回事件
  VoidCallback? unRegisterFunc;
  if (backButtonBehavior == BackButtonBehavior.ignore) {
    unRegisterFunc = BotToastWidgetsBindingObserver.singleton.registerPopListener(() {
      return true;
    });
  } else if (backButtonBehavior == BackButtonBehavior.close) {
    unRegisterFunc = BotToastWidgetsBindingObserver.singleton.registerPopListener(() {
      dismissFunc();
      unRegisterFunc?.call();
      unRegisterFunc = null;
      return true;
    });
  }

  cancelFunc = showWidget(
      groupKey: groupKey,
      key: key,
      toastBuilder: (_) {
        return KeyboardSafeArea(
          enable: enableKeyboardSafeArea == true,
          child: ProxyDispose(disposeCallback: () {
            cache.remove(dismissFunc);
            if (observerProxy != null) {
              BotToastNavigatorObserver.unregister(observerProxy);
            }
            timer?.cancel();
            onClose?.call();
            unRegisterFunc?.call();
          }, child: Builder(builder: (BuildContext context) {
            final TextStyle textStyle = Theme.of(context).textTheme.bodyMedium!;
            Widget child = DefaultTextStyle(
                style: textStyle,
                child: Stack(children: <Widget>[
                  Listener(
                    onPointerDown: clickClose == true ? (_) => dismissFunc() : null,
                    behavior: allowClick == true ? HitTestBehavior.translucent : HitTestBehavior.opaque,
                    child: const SizedBox.expand(),
                  ),
                  IgnorePointer(
                    child: Container(color: backgroundColor),
                  ),
                  IgnorePointer(
                    ignoring: ignoreContentClick == true,
                    child: toastBuilder(dismissFunc),
                  )
                ]));
            return warpWidget != null ? warpWidget(dismissFunc, child) : child;
          })),
        );
      });

  return dismissFunc;
}