Flutter 常用按钮总结

4字数 489阅读 7351

博客地址: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 更改状态栏颜色

推荐阅读更多精彩内容