如何在 flutter 中显示自定义吐司对话框?
How to show custom toast dialog in flutter?
我想显示自定义 toast
(我自己的小部件布局)。我知道如何显示自定义 alert dialogue
,但这不是我想要的。
因为,Alert dialogue
:
- 有黑色背景
- 显示时防止触摸
- 必须手动关闭
我不想使用 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);
我想显示自定义 toast
(我自己的小部件布局)。我知道如何显示自定义 alert dialogue
,但这不是我想要的。
因为,Alert dialogue
:
- 有黑色背景
- 显示时防止触摸
- 必须手动关闭
我不想使用 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);