flutter toast插件 OKToast的介绍
文章目录
OKToast 是一款 在 flutter 上 使用的 toast 插件
使用简单, 可定制性强, 纯 flutter, 调用不用 context
安装
查看文档: https://pub.dartlang.org/packages/oktoast#-installing-tab-
在 pubspec 引入
1dependencies:
2 oktoast: ^2.2.0 # 这一步请查询pub的最新版本
获取包:
$ flutter packages get
引入:
import 'package:oktoast/oktoast.dart';
使用
在代码中定义 OKToast 组件
包裹你的 MaterialApp,不是包裹你的 Scaffold
包裹你的 MaterialApp,不是包裹你的 Scaffold
包裹你的 MaterialApp,不是包裹你的 Scaffold
1class MyApp extends StatelessWidget {
2 @override
3 Widget build(BuildContext context) {
4 return OKToast( // 这一步
5 child: new MaterialApp(
6 title: 'Flutter Demo',
7 theme: new ThemeData(
8 primarySwatch: Colors.blue,
9 ),
10 home: new MyHomePage(),
11 ),
12 );
13 }
14}
这一步解释一下,因为一般情况下,一个 flutter 应用应该只有一个 MaterialApp(或是 WidgetsApp/CupertinoApp), 这里包裹后,可以缓存 Context 到 内存中,后续在调用显示时,不用传入 BuildContext
这样能满足一部分用户在无 context 的情况下调用 showToast
方法
调用
文本 toast
1showToast("hello world"); // 可选属性看自己需求
自定义 widget
1Widget widget = Center(
2 child:Container(
3 color:Colors.white,
4 child:Icon(Icons.add),
5 ),
6);
7showToastWidget(widget);
使用如下代码的效果
1
2 void _showCustomWidgetToast() {
3 var w = Center(
4 child: Container(
5 padding: const EdgeInsets.all(5),
6 color: Colors.black.withOpacity(0.7),
7 child: Row(
8 children: <Widget>[
9 Icon(
10 Icons.add,
11 color: Colors.white,
12 ),
13 Text(
14 '添加成功',
15 style: TextStyle(color: Colors.white),
16 ),
17 ],
18 mainAxisSize: MainAxisSize.min,
19 ),
20 ),
21 );
22 showToastWidget(w);
23 }
简单的 toast 实现
其实简单的方案,直接使用 Overlay 就可以了,不需要插件只需要一个简单的工具类,而且代码量并不大
1class ToastHelper {
2 static void showToast(BuildContext context, String text) {
3 const style = TextStyle(color: Colors.white, fontSize: 14.0);
4
5 Widget widget = Center(
6 child: Container(
7 color: Colors.black.withOpacity(0.5),
8 padding: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0),
9 child: Text(
10 text,
11 style: style,
12 ),
13 ),
14 );
15 var entry = OverlayEntry(
16 builder: (_) => widget,
17 );
18
19 Overlay.of(context).insert(entry);
20
21 Timer(const Duration(seconds: 2), () {
22 entry?.remove();
23 });
24 }
25}
那么为什么要用 OKToast 呢?
- 不用 context,方便一些在网络层的提示
- 比较方便的自定义,支持自建 widget
- 有一些小特性,比如软键盘弹出时自动移动位置防遮挡
- 支持手动隐藏 toast
进阶使用
隐藏已出现的 toast
有如下的方式可以隐藏
隐藏所有的 toast
手动隐藏:调用这个方法就可以关闭所有的 toast 了
1dismissAllToast();
在显示 toast 时隐藏之前显示的所有 toast,其实是根据这个参数在方法内调用dismissAllToast
1showToast("msg", dismissOtherToast: true);
全局设置隐藏之前的属性,这里设置后,每次当你显示新的 toast 时,旧的就会被关闭
1OKToast(
2 dismissOtherOnShow: true,
3 ...
4)
隐藏单独的 toast
每一个 showToast/showToastWidget 方法会有一个返回值,类型是 ToastFuture
1var future = showToast("msg");
2future.dismiss(); // 隐藏指定的toast
自定义属性
OKToast 组件有丰富的自定义属性
backgroundColor: 背景颜色
duration: 延迟隐藏时间
onDismiss: 隐藏时的回调
position: toast 的位置
radius: 圆角的尺寸
textAlign: 文字在内部的对齐方式
textDirection: ltr 或 rtl
textPadding: 文本距离边框的 padding
textStyle: 文本的样式
本文完整的 main.dart
1import 'dart:async';
2
3import 'package:flutter/material.dart';
4import 'package:oktoast/oktoast.dart';
5
6void main() => runApp(new MyApp());
7
8class MyApp extends StatelessWidget {
9 // This widget is the root of your application.
10 @override
11 Widget build(BuildContext context) {
12 return OKToast(
13 dismissOtherOnShow: true,
14 child: new MaterialApp(
15 title: 'Flutter Demo',
16 theme: new ThemeData(
17 // This is the theme of your application.
18 //
19 // Try running your application with "flutter run". You'll see the
20 // application has a blue toolbar. Then, without quitting the app, try
21 // changing the primarySwatch below to Colors.green and then invoke
22 // "hot reload" (press "r" in the console where you ran "flutter run",
23 // or press Run > Flutter Hot Reload in IntelliJ). Notice that the
24 // counter didn't reset back to zero; the application is not restarted.
25 primarySwatch: Colors.blue,
26 ),
27 home: new MyHomePage(title: 'Flutter Demo Home Page'),
28 ),
29 );
30 }
31}
32
33class MyHomePage extends StatefulWidget {
34 MyHomePage({Key key, this.title}) : super(key: key);
35
36 // This widget is the home page of your application. It is stateful, meaning
37 // that it has a State object (defined below) that contains fields that affect
38 // how it looks.
39
40 // This class is the configuration for the state. It holds the values (in this
41 // case the title) provided by the parent (in this case the App widget) and
42 // used by the build method of the State. Fields in a Widget subclass are
43 // always marked "final".
44
45 final String title;
46
47 @override
48 _MyHomePageState createState() => new _MyHomePageState();
49}
50
51class _MyHomePageState extends State<MyHomePage> {
52 int _counter = 0;
53
54 void _showToast() {
55 showToast("msg");
56 }
57
58 @override
59 Widget build(BuildContext context) {
60 return Scaffold(
61 appBar: AppBar(
62 title: Text("OKToast示例"),
63 ),
64 body: ListView(
65 children: <Widget>[
66 RaisedButton(
67 child: Text('文字toast'),
68 onPressed: _showToast,
69 ),
70 RaisedButton(
71 child: Text('自定义Widget Toast'),
72 onPressed: _showCustomWidgetToast,
73 ),
74 RaisedButton(
75 child: Text('ToastHelper '),
76 onPressed: () => ToastHelper.showToast(context, "toast helper"),
77 ),
78 ],
79 ),
80 );
81 }
82
83 void _showCustomWidgetToast() {
84 var w = Center(
85 child: Container(
86 padding: const EdgeInsets.all(5),
87 color: Colors.black.withOpacity(0.7),
88 child: Row(
89 children: <Widget>[
90 Icon(
91 Icons.add,
92 color: Colors.white,
93 ),
94 Text(
95 '添加成功',
96 style: TextStyle(color: Colors.white),
97 ),
98 ],
99 mainAxisSize: MainAxisSize.min,
100 ),
101 ),
102 );
103 showToastWidget(w);
104 }
105}
106
107class ToastHelper {
108 static void showToast(BuildContext context, String text) {
109 const style = TextStyle(color: Colors.white, fontSize: 14.0);
110
111 Widget widget = Center(
112 child: Material(
113 child: Container(
114 color: Colors.black.withOpacity(0.5),
115 padding: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0),
116 child: Text(
117 text,
118 style: style,
119 ),
120 ),
121 ),
122 );
123 var entry = OverlayEntry(
124 builder: (_) => widget,
125 );
126
127 Overlay.of(context).insert(entry);
128
129 Timer(const Duration(seconds: 2), () {
130 entry?.remove();
131 });
132 }
133}
和 fluttertoast 的对比
为什么不使用 fluttertoast 呢, 我曾经也给 fluttertoast 提交过 PR
但是这个插件本身是依赖于原生的,android 端不可避免在默认样式上会受到 rom 的影响,并且各种属性会有兼容问题
我信奉的原则是,UI 层级的问题,直接在 flutter 端解决
后记
代码使用并不复杂, 如果对你有帮助解决了问题, 可以给我赞赏 ,请我喝咖啡(下方二维码)