Flutter 常用按钮总结

博客地址:flutterall.com

本文我们就一起聊一聊Flutter中的Button。由于Flutter是跨平台的,所以有适用于Android和iOS的两种风格的组件。一套是Google极力推崇的Material,一套是iOS的Cupertino风格的组件。无论哪种风格,都是通用的。

Material与Cupertino风格比较

控件 Material Cupertino
Button
RaisedButton
CupertinoButton
DatePick
showDatePicker
CupertinoDatePicker

从多年与设计师打交道来看,App更青睐于iOS,很多Android的App做的跟iOS一样一样的,就连设计个按钮图标啥的都是一样。

Material Style

RaisedButton(Material风格的按钮)


RaisedButton({
    Key key,
  //点击按钮的回调出发事件
    @required VoidCallback onPressed,
  //水波纹高亮变化回调
    ValueChanged<bool> onHighlightChanged,
  //按钮的样式(文字颜色、按钮的最小大小,内边距以及shape)[ Used with [ButtonTheme] and [ButtonThemeData] to define a button's base
//colors, and the defaults for the button's minimum size, internal padding,and shape.]
    ButtonTextTheme textTheme,
    //文字颜色
    Color textColor,
    //按钮被禁用时的文字颜色
    Color disabledTextColor,
    //按钮的颜色
    Color color,
    //按钮被禁用时的颜色  
    Color disabledColor,
    //按钮的水波纹亮起的颜色
    Color highlightColor,
    //水波纹的颜色
    Color splashColor,
    //按钮主题高亮
    Brightness colorBrightness,
    //按钮下面的阴影长度
    double elevation,
    //按钮高亮时的下面的阴影长度
    double highlightElevation,
    double disabledElevation,
    EdgeInsetsGeometry padding,
    ShapeBorder shape,
    Clip clipBehavior = Clip.none,
    MaterialTapTargetSize materialTapTargetSize,
    Duration animationDuration,
    Widget child,
  }

一张图了解RaisedButton

图示RaisedButton

Code


RaisedButton(
            textTheme: ButtonTextTheme.accent,
            color: Colors.teal,
            highlightColor: Colors.deepPurpleAccent,
            splashColor: Colors.deepOrangeAccent,
            colorBrightness: Brightness.dark,
            elevation: 50.0,
            highlightElevation: 100.0,
            disabledElevation: 20.0,
            onPressed: () {
              //TODO
            },
            child: Text(
              'RaisedButton',
              style: TextStyle(color: Colors.white, fontSize: 40),
            ),
          )

RaisedButton

FloatingActionButton(悬浮按钮)

如果有时间,可以看看FlatButton的Material设计理念,效果还是很不错的。
例如:

FloatingActionButton

FloatingActionButton({
    Key key,
    //  按钮上的组件,可以是Text、icon, etc.
    this.child,
    //长按提示
    this.tooltip,
    // child的颜色(尽在child没有设置颜色时生效)
    this.foregroundColor,
    //背景色,也就是悬浮按键的颜色
    this.backgroundColor,
    this.heroTag = const _DefaultHeroTag(),
    //阴影长度
    this.elevation = 6.0,
    //高亮时阴影长度
    this.highlightElevation = 12.0,
    //按下事件回调
    @required this.onPressed,
    //是小图标还是大图标
    this.mini = false,
    //按钮的形状(例如:矩形Border,圆形图标CircleBorder)
    this.shape = const CircleBorder(),
    this.clipBehavior = Clip.none,
    this.materialTapTargetSize,
    this.isExtended = false,
  })

Code

FloatingActionButton(
      child: Icon(Icons.access_alarm),
      tooltip: "ToolTip",
      foregroundColor: Colors.white,
      backgroundColor: Colors.deepPurple,
      shape: const Border(),
      onPressed: () {
        //click callback
      },
    )

FlatButton

一个扁平的Material按钮

FlatButton.gif

FlatButton({
    Key key,
    @required VoidCallback onPressed,
    ValueChanged<bool> onHighlightChanged,
    ButtonTextTheme textTheme,
    Color textColor,
    Color disabledTextColor,
    Color color,
    Color disabledColor,
    Color highlightColor,
    Color splashColor,
    Brightness colorBrightness,
    EdgeInsetsGeometry padding,
    ShapeBorder shape,
    Clip clipBehavior = Clip.none,
    MaterialTapTargetSize materialTapTargetSize,
    @required Widget child,
  })

可以看到属性跟RaisedButton类似,这里不多说了。


FlatButton(
        onPressed: () {},
        child: Text(
          "FlatBtn",
          style: TextStyle(fontSize: 20, color: Colors.deepPurple),
        ));

IconButton

图标按钮,按下时会产生水波纹效果。

IconButton

IconButton({
//这几个属性跟前面讲的几个差不多,这里就不再讲了。如有疑问,请留言。
    Key key,
    this.iconSize = 24.0,
    this.padding = const EdgeInsets.all(8.0),
    this.alignment = Alignment.center,
    @required this.icon,
    this.color,
    this.highlightColor,
    this.splashColor,
    this.disabledColor,
    @required this.onPressed,
    this.tooltip
  })

IconButton.gif

DropdownButton

Material Style 下拉菜单按钮

DropdownButton
DropdownButton({
    Key key,
 //要显示的列表
      List<DropdownMenuItem<T>> @required this.items,
 //下拉菜单选中的值(注意:在初始化时,要么为null,这时显示默认hint的值;
 // 如果自己设定值,则值必须为列表中的一个值,如果不在列表中,会抛出异常)
    T value,
//默认显示的值
    Widget hint,
    Widget disabledHint,
//选中时的回调
   ValueChanged<T>  @required this.onChanged,
    this.elevation = 8,
    this.style,
    this.iconSize = 24.0,
    this.isDense = false,
    this.isExpanded = false,
  })

  • items

//返回城市列表,写法一
List<DropdownMenuItem> _getItems() {
  List<DropdownMenuItem> items = new List();
  //value 表示DropdownButton.onChanged的返回值
  items.add(DropdownMenuItem(child: Text("北京"), value: "BJ"));
  items.add(DropdownMenuItem(child: Text("上海"), value: "SH"));
  items.add(DropdownMenuItem(child: Text("广州"), value: "GZ"));
  items.add(DropdownMenuItem(child: Text("深圳"), value: "SZ"));
  return items;
}

//返回城市列表,写法二
List<DropdownMenuItem<String>> _getCityList() {
  var list = ["北京", "上海", "广州", "深圳"];
  return list.map((item) => DropdownMenuItem(
    value: item,
    child: Text(item),
  )).toList();
}

由于我们在点击每一个条目后,展示的选中条目会变化,所以DropdownButton应当继承StatefulWidget,在选中条目后也就是onChange的回调中使用setState((){})更新对象的状态。

  • DropdownButton

DropdownButton应当继承StatefulWidget


class FlutterDropdownButtonStatefulWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _DropdownState();
  }
}

  • _DropdownState

//下划线开头表示私有
class _DropdownState extends State<FlutterDropdownButtonStatefulWidget> {
//  下拉菜单选中的值(注意:在初始化时,要么为null,这时显示默认hint的值;
// 如果自己设定值,则值必须为列表中的一个值,如果不在列表中,会抛出异常)
  String selectValue;

  @override
  Widget build(BuildContext context) {
    return DropdownButton(
      //要显示的条目
      items: _getItems(),
      //默认显示的值
      hint: Text("请选择城市"),
      //下拉菜单选中的值(注意:在初始化时,要么为null,这时显示默认hint的值;
      // 如果自己设定值,则值必须为列表中的一个值,如果不在列表中,会抛出异常)
      value: selectValue,
      onChanged: (itemValue) {//itemValue为选中的值
        print("itemValue=$itemValue");
        _onChanged(itemValue);
      },
    );
  }
  _onChanged(String value) {
    //更新对象的状态
    setState(() {
      selectValue = value;
    });
  }
}
  • print log
    print log
  • 最终效果
    DropdownButton

PopupMenuButton

当菜单隐藏时,点击并且调用onSelected时显示一个弹出式菜单列表

FlutterPopupMenuButton.gif

PopupMenuButton({
    Key key,
//构建弹出式列表数据
    PopupMenuItemBuilder<T> @required this.itemBuilder,
//初始值
   T initialValue,
//选中时的回调
 PopupMenuItemSelected<T> onSelected;,
//当未选中任何条目后弹窗消失时的回调
     final PopupMenuCanceled onCanceled;,
//
    this.tooltip,
//弹窗阴影高度
    this.elevation = 8.0,
//边距
    this.padding = const EdgeInsets.all(8.0),
//弹窗的位置显示的组件,默认为三个点...
    this.child,
//跟child效果一致
    this.icon,
//弹窗偏移位置
    this.offset = Offset.zero,
  })

  • Code

import 'package:flutter/material.dart';

class FlutterPopupMenuButton extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _PopupMenuState();
}

const List<String> models = const <String>['白天模式', '护眼模式', '黑夜模式'];

class _PopupMenuState extends State<FlutterPopupMenuButton> {
  String title = models[0];

  List<PopupMenuEntry<String>> _getItemBuilder() {
    return models
        .map((item) => PopupMenuItem<String>(
              child: Text(item),
              value: item,//value一定不能少
            ))
        .toList();
  }

  void _select(String value) {
    setState(() {
      title = value;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
          actions: <Widget>[
            PopupMenuButton<String>(
              onSelected: _select,
              itemBuilder: (BuildContext context) {
                return _getItemBuilder();
              },
            )
          ],
        ),
      ),
    );
  }

//  List<PopupMenuEntry> _getItemBuilder() {
//    List<PopupMenuEntry> list = List();
//    list.add(PopupMenuItem(
//      child: Text("白天模式"),
//      value: "Day",
//    ));
//    list.add(PopupMenuItem(
//      child: Text("黑夜模式"),
//      value: "Night",
//    ));
//    return list;
//  }

}

ButtonBar

水平排列的按钮组

ButtonBar

const ButtonBar({
    Key key,
//子组件的间隔样式
    this.alignment = MainAxisAlignment.end,
    this.mainAxisSize = MainAxisSize.max,
//子children
    this.children = const <Widget>[],
  })

MainAxisAlignment,之间的博客中讲过。


class FlutterButtonBar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ButtonBar(children: <Widget>[
      Text("ButtonBar0"),
      Icon(Icons.ac_unit),
      Text("ButtonBar1")
    ], );
  }
}

到这里,终于把Material Style的大部分Button讲完了,开始下一个。

本地代码地址

Flutter 豆瓣客户端,诚心开源
Flutter Container
Flutter SafeArea
Flutter Row Column MainAxisAlignment Expanded
Flutter Image全解析
Flutter 常用按钮总结
Flutter ListView豆瓣电影排行榜
Flutter Card
Flutter Navigator&Router(导航与路由)
OverscrollNotification不起效果引起的Flutter感悟分享
Flutter 上拉抽屉实现
Flutter 豆瓣客户端,诚心开源
Flutter 更改状态栏颜色

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,071评论 4 62
  • 9月1日早上,媳妇看见我慢悠悠地醒来,微笑着告诉我说,昨天晚上你睡得真好,真香!多久没有睡这么好的觉了。整...
    水墨山风王仲波阅读 368评论 0 5
  • 20171002 周一 #口号(如:父母的高度是孩子的起点)# 孩子第二个30天目标: 认真吃饭,多吃菜 妈妈第...
    文子16阅读 268评论 0 0
  • 我想了很久,也不知道有多久。 终于开口告诉了她 她坐在阳光照耀下的椅子,说:“你知道…这要考虑很多,而且现在已经不...
    楠啊啊阅读 197评论 0 0
  • 西冷牛排 有嚼劲 牛外脊的肉 肉的外围有白色肉筋 勒眼牛排 q弹口感 肥瘦皆有 油画丰富 菲力牛排 牛腹腔 肉质鲜...
    木子型男阅读 202评论 1 0