Flutter入门(37):Flutter 组件之 SnackBar 详解

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: (){

        },
      ),
    );
  }
}
SnackBar normal.png

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");
        },
      ),
    );
  }
}
Snack Shape.png

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("是要成为海贼王的男人"),
            ],
          ),
        ],
      ),
    );
  }
}
SnackBar customer.png

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 是一个很简单的控件,多加练习吧。

你可能感兴趣的:(Flutter入门(37):Flutter 组件之 SnackBar 详解)