如何在 flutter 中显示自定义吐司对话框?

How to show custom toast dialog in flutter?

我想显示自定义 toast(我自己的小部件布局)。我知道如何显示自定义 alert dialogue,但这不是我想要的。

因为,Alert dialogue:

  1. 有黑色背景
  2. 显示时防止触摸
  3. 必须手动关闭

我不想使用 flutter toast 库,因为我无法用它制作自定义布局。

我想在所有其他小部件之上显示我自己的布局,并使其在一段时间后消失。此外,它在显示时不应阻止任何输入。

您可以添加this library来添加和自定义您自己的祝酒词。

Widget widget = Center(
      child: ClipRRect(
        borderRadius: BorderRadius.circular(30.0),
        child: Container(
          width: 40.0,
          height: 40.0,
           color: Colors.grey.withOpacity(0.3),
          child: Icon(
            Icons.add,
            size: 30.0,
            color: Colors.green,
          ),
        ),
      ),
    );

    ToastFuture toastFuture = showToastWidget(
      widget,
      duration: Duration(seconds: 3),
      onDismiss: () {
        print("the toast dismiss"); // the method will be called on toast dismiss.
      },
    );

自定义吐司

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

class Toast {
  static void show(
    String msg,
    BuildContext context) {
    Color textColor = Colors.white;
    Color backgroundColor = Colors.blueAccent;
    dismiss();
    Toast._createView(msg, context, backgroundColor, textColor);
  }

  static OverlayEntry _overlayEntry;
  static bool isVisible = false;

  static void _createView(
    String msg,
    BuildContext context,
    Color background,
    Color textColor,
  ) async {
    var overlayState = Overlay.of(context);

    final themeData = Theme.of(context);

    _overlayEntry = new OverlayEntry(
      builder: (BuildContext context) => _ToastAnimatedWidget(
        child: Container(
          width: MediaQuery.of(context).size.width,
          child: Container(
            alignment: Alignment.center,
            width: MediaQuery.of(context).size.width,
            child: Container(
              decoration: BoxDecoration(
                color: background,
                borderRadius: BorderRadius.circular(20),
              ),
              margin: EdgeInsets.symmetric(horizontal: 20),
              padding: EdgeInsets.fromLTRB(16, 10, 16, 10),
              child: Text(
                msg,
                softWrap: true,
                style: themeData.textTheme.body1.copyWith(
                  fontFamily: 'intel',
                  color: Colors.white,
                ),
              ),
            ),
          ),
        ),
      ),
    );
    isVisible = true;
    overlayState.insert(_overlayEntry);
  }

  static dismiss() async {
    if (!isVisible) {
      return;
    }
    isVisible = false;
    _overlayEntry?.remove();
  }
}
class _ToastAnimatedWidget extends StatefulWidget {
  _ToastAnimatedWidget({
    Key key,
    @required this.child,
  }) : super(key: key);

  final Widget child;

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

class _ToastWidgetState extends State<_ToastAnimatedWidget>
    with SingleTickerProviderStateMixin {

  bool get _isVisible => true; //update this value later

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
        bottom: 50,
        child: AnimatedOpacity(
          duration: Duration(seconds: 2),
          opacity: _isVisible ? 1.0 : 0.0,
          child: widget.child,
        )
    );
  }
}

通话

Toast.show(ApiContent.something_wrong, context);