1. 基本介绍
SnackBar 是一个常见的底部消息弹框。
2. 示例代码
代码下载地址。如果对你有帮助的话记得给个关注,代码会根据我的 Flutter 专题不断更新。
3. 属性介绍
SnackBar属性 | 介绍 |
---|---|
content | @required 左侧内容 Widget |
backgroundColor | 背景色 |
elevation | 阴影高度 |
shape | 形状 ShapeBorder |
behavior | SnackBarBehavior.fixed 是贴合屏幕边框的,SnackBarBehavior.floating 是悬浮出来的一个弹框 |
action | SnackBarAction,右侧事件按钮 |
duration | 弹框展示时长,默认为 Duration(milliseconds: 4000) |
animation | 动画效果,没啥太大用,使用 showSnackBar,会被自带动画替换 |
onVisible | SnackBar 展示在屏幕上时的回调函数 |
SnackBarAction属性 | 介绍 |
---|---|
textColor | 字体颜色 |
disabledTextColor | 不可用时字体颜色 |
label | 事件文字 |
onPressed | @required 点击事件 |
4. SnackBar 详解
4.1 简单的 SnackBar
import 'package:flutter/material.dart';
class FMSnackBarVC extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(title: Text("SnackBar"),),
body: ListView(
children: [
FMNormalSnackBarBtn(),
],
),
);
}
}
class FMNormalSnackBarBtn extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return RaisedButton(
child: Text("Noraml SnackBar"),
onPressed: (){
Scaffold.of(context).showSnackBar(_normalSnackBar());
},
);
}
SnackBar _normalSnackBar(){
return SnackBar(
content: Text("SnackBar"),
backgroundColor: Colors.grey,
elevation: 10,
behavior: SnackBarBehavior.fixed,
duration: Duration(seconds: 5),
onVisible: (){
print("onVisible");
},
action: SnackBarAction(
label: "SnackBarAction",
textColor: Colors.red,
disabledTextColor: Colors.green,
onPressed: (){
},
),
);
}
}
4.2 onVisible、SnackBarAction 事件详解
SnackBar 中有两处回调函数,一个是 onVisible,另一个就是 SnackBarAction.onPressed。
事件 | 触发方式 |
---|---|
onVisible | SnackBar 完全弹出时调用 |
SnackBarAction.onPressed | 右侧 Action 点击时触发 |
4.3 颜色样式
我们新增一个样式的 Snack。
class FMSnackBarVC extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(title: Text("SnackBar"),),
body: ListView(
children: [
FMNormalSnackBarBtn(),
FMShapeSnackBarBtn(),
],
),
);
}
}
class FMShapeSnackBarBtn extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return RaisedButton(
child: Text("Shape SnackBar"),
onPressed: (){
Scaffold.of(context).showSnackBar(_shapeSnackBar());
},
);
}
SnackBar _shapeSnackBar(){
return SnackBar(
content: Text("SnackBar"),
backgroundColor: Colors.lightBlueAccent,
elevation: 10,
behavior: SnackBarBehavior.floating,
duration: Duration(seconds: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
side: BorderSide(
color: Colors.yellow,
width: 2,
),
),
onVisible: (){
print("onVisible");
},
action: SnackBarAction(
label: "SnackBarAction",
textColor: Colors.red,
disabledTextColor: Colors.green,
onPressed: (){
print("SnackBarAction.onPressed");
},
),
);
}
}
4.4 自定义 content 的 SnackBar
上边只是简单的文本消息,这里写一个复杂一点的示例,其实 content 本身就是一个自由的 Widget,不用太过古板。
class FMSnackBarVC extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(title: Text("SnackBar"),),
body: ListView(
children: [
FMNormalSnackBarBtn(),
FMShapeSnackBarBtn(),
FMCustomSnackBarBtn(),
],
),
);
}
}
class FMCustomSnackBarBtn extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return RaisedButton(
child: Text("Custom SnackBar"),
onPressed: (){
Scaffold.of(context).hideCurrentSnackBar();
Scaffold.of(context).showSnackBar(_customSnackBar());
},
);
}
SnackBar _customSnackBar(){
return SnackBar(
content: _content(),
backgroundColor: Colors.lightBlueAccent,
elevation: 10,
behavior: SnackBarBehavior.floating,
duration: Duration(seconds: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
side: BorderSide(
color: Colors.yellow,
width: 2,
),
),
onVisible: (){
print("onVisible");
},
action: SnackBarAction(
label: "SnackBarAction",
textColor: Colors.red,
disabledTextColor: Colors.green,
onPressed: (){
print("SnackBarAction.onPressed");
},
),
);
}
Widget _content(){
return Container(
height: 100,
child: Row(
children: [
Container(
width: 60,
child: Image.network('http://tiebapic.baidu.com/forum/w%3D580/sign=a96ca741eafaaf5184e381b7bc5594ed/7ea6a61ea8d3fd1f2643ad5d274e251f95ca5f38.jpg'),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("我叫路飞"),
Text("是要成为海贼王的男人"),
],
),
],
),
);
}
}
5. SnackBar 进阶
SnackBar 的使用其实非常简单,但是我们来细究一下他的机制。我们连续点击不同弹框,会发现并不会立即弹出下一个,而是按照 duration 展示每一个 SnackBar,如果大量调用,就会一直在最下方等待弹出,这是肯定没法接受的。
(示例中已经做了取消 SnackBar 处理,所以连续点击并没有问题。)
取消弹框有以下两种方式。
Scaffold.of(context).hideCurrentSnackBar();
Scaffold.of(context).removeCurrentSnackBar();
所以建议这么使用,showSnackBar 之前,先隐藏当前 SnackBar。
Widget build(BuildContext context) {
// TODO: implement build
return RaisedButton(
child: Text("Custom SnackBar"),
onPressed: (){
Scaffold.of(context).hideCurrentSnackBar();
// Scaffold.of(context).removeCurrentSnackBar();
Scaffold.of(context).showSnackBar(_normalSnackBar());
},
);
}
6. 技术小结
SnackBar 是一个很简单的控件,多加练习吧。