Flutter实战(三)---SnackBar

Snackbar是Android 5.0新特性——Material Design中的一个控件,用来代替Toast,Snackbar与Toast的主要区别是:Snackbar可以滑动退出,也可以处理用户交互(点击)事件。

Snackbar的特性

  • Snackbar会在超时或者用户在屏幕其他地方触摸之后自动消失
  • 可以在屏幕上滑动关闭
  • 出现时不会阻碍用户在屏幕上的输入
  • 屏幕上同时最多只能显示一个Snackbar
  • 如果在屏幕上有一个Snackbar的情况下再显示一个Snackbar,则先将当前显示的Snackbar隐藏后再显示新的Snackbar
  • 可以在Snackbar中添加一个按钮,处理用户点击事件

在Flutter开发时,对于提示性信息,有人已经想到写一个插件去调用Android原生的Toast,且不说还要兼容IOS,这种反历史潮流的行为,一方面伤害了移动端的UI统一体验,另一方面对于主打Material Design设计的Flutter来说,也是不符合Google开发这套框架的初衷的。

言归正传,我们重点看看怎么使用这个控件, SnackBar是通过Scaffold的showSnackBar方法来显示的。所以要显示一个SnackBar,要先拿到Scaffold。

根布局使用Scaffold

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: new Text(
            "登录",
            style: new TextStyle(
              fontSize: 18.0,
              fontWeight: FontWeight.bold,
            ),
          ),
          elevation: 0.0,
          centerTitle: true,
        ),
        body: new RaisedButton(
          onPressed: () async {
            login(context);
          },
          color: Color(0xFFE60012),
          child: new Padding(
              padding: const EdgeInsets.all(13.0),
              child: new Text(
                "登录",
                style: new TextStyle(
                    color: Colors.white,
                    fontSize: 18.0,
                    fontWeight: FontWeight.bold),
              )),
          shape: new RoundedRectangleBorder(
              borderRadius: new BorderRadius.circular(30.0)),
        ));
  }

显示SnackBar

首先创建一个SnackBar,再通过Scaffold的方法来显示。

  void login(BuildContext context) {
    if (userPhone.isEmpty) {
      final snackBar = new SnackBar(content: new Text("手机号不能为空"));
      Scaffold.of(context).showSnackBar(snackBar);
      return;
    }
  }

给SnackBar添加一个操作按钮

有时候,我们可能会想在显示的提示信息上添加一些操作。例如提示用户删除了一条消息,可以在提示信息上添加一个撤消的按钮,要达到这个效果,我们可以在SnackBar上添加一个操作按钮。

    final snackBar = new SnackBar(
      content: new Text('删除信息'),
      action: new SnackBarAction(
          label: '撤消',
          onPressed: () {
            // do something to undo
          }),
    );

注意事项

当BuildContext在Scaffold之前时,调用Scaffold.of(context)会报错。这时可以通过Builder Widget来解决,代码如下:

     body: new Builder(builder: (BuildContext context) {
        return Container(
            margin: new EdgeInsets.all(15.0),
            child: ListView(
              children: <Widget>[
                SizedBox(
                  height: 30,
                ),
                new Center(
                  child: new Stack(
                      alignment: AlignmentDirectional.topCenter,
                      children: <Widget>[
                        new Image.asset("images/pair_guide_icon.png"),
                        new Column(children: <Widget>[
                          SizedBox(
                            height: 30,
                          ),
                          new Text(
                            "长按3秒“播放/暂停”键开启蓝牙",
                            style: new TextStyle(
                              fontSize: 18.0,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ]),
                      ]),
                ),
                new SizedBox(
                  height: 30.0,
                ),
                new RaisedButton(
                  onPressed: isBtnEnabled
                      ? () {
                          searchDevice(context);
                        }
                      : null,
                  color: isBtnEnabled ? Color(0xFFE60012) : Color(0xFFEBEBEB),
                  child: new Padding(
                      padding: const EdgeInsets.all(13.0),
                      child: new Text(pairBtnStatus,
                          style: new TextStyle(
                            fontSize: 18.0,
                            fontWeight: FontWeight.bold,
                            color: isBtnEnabled ? Colors.white : Colors.black,
                          ))),
                  shape: new RoundedRectangleBorder(
                      borderRadius: new BorderRadius.circular(30.0)),
                ),
                new SizedBox(
                  height: 10.0,
                ),
                new Center(
                  child: FlatButton(
                    shape: new RoundedRectangleBorder(
                        borderRadius: new BorderRadius.circular(30.0)),
                    child: new Text("需要帮助"),
                    onPressed: () async {
                      String callPhone = "tel:4008123456";
                      if (await canLaunch(callPhone)) {
                        await launch(callPhone);
                      } else {
                        throw 'Could not launch $callPhone';
                      }
                    },
                  ),
                ),
              ],
            ));
      }),

拿到context后,就可以尽情使用SnackBar了:

  void searchDevice(BuildContext context) {
    BleManager.getInstance().setOnBleState((BluetoothState state) {
      if (state != BluetoothState.on) {
        final snackBar = new SnackBar(content: new Text("请先打开蓝牙"));
        Scaffold.of(context).showSnackBar(snackBar);
      } else {
        BleManager.getInstance().startScan();
      }
    });
  }

你可能感兴趣的:(Flutter)