Flutter 74: 图解基本 DropdownButton 下拉选项框按钮

      和尚对于 Flutter 并不系统,总是遇到问题才会准备尝试,今天和尚准备学习一下下拉选择框;Android 提供了便利的 SpinnerFlutter 对应的是 DropdownButton

源码分析

DropdownButton({
    Key key,
    @required this.items,       // 下拉选项列表
    this.selectedItemBuilder,   // 选项 item 构造器
    this.value,                 // 选中内容
    this.hint,                  // 启动状态下默认内容
    this.disabledHint,          // 禁用状态下默认内容
    @required this.onChanged,   // 选择 item 回调
    this.elevation = 8,         // 阴影高度
    this.style,                 // 选项列表 item 样式
    this.underline,             // 按钮下划线
    this.icon,                  // 下拉按钮图标
    this.iconDisabledColor,     // 禁用状态下图标颜色
    this.iconEnabledColor,      // 启动时图标颜色
    this.iconSize = 24.0,       // 图标尺寸
    this.isDense = false,       // 是否降低按钮高度
    this.isExpanded = false,    // 是否将下拉列表内容设置水平填充
})

const DropdownMenuItem({
    Key key,
    this.value,             // 对应选中状态内容
    @required this.child,   // 下拉列表 item 内容
})

      分析源码可知,itemsonChanged 回调是必须参数,且在不同状态下,展示的效果不同;其中 itemsonChangednull 时为禁用状态,和尚接下来逐一分析各属性;

案例分析

  1. items 为下拉选项列表,onChanged 为选中回调;两者其中一个为 null 时为按钮禁用状态,不可点击,默认下拉 icon 为灰色;items 不为空时,需为相同类型的 DropdownMenuItem 类型列表;
DropdownButton(items: null, onChanged: null);

DropdownButton(items: [
  DropdownMenuItem(child: Text('北京')),
  DropdownMenuItem(child: Text('天津')),
  DropdownMenuItem(child: Text('河北'))
], onChanged: (value) {});
  1. icon 为下拉按钮右侧图标,iconSize 为下拉按钮图标尺寸,禁用和启动状态下均可设置;若 icon 设置尺寸以 icon 尺寸为准;
icon: Icon(Icons.arrow_right),
// icon: Icon(Icons.arrow_right, color: Colors.blue.withOpacity(0.7), size: 60),
iconSize: 40,
  1. iconDisabledColor 为禁用状态下设置 icon 颜色,iconEnabledColor 为按钮启用状态下设置 icon 颜色;但若 icon 设置固定颜色后,以 icon 设置为准;
// 禁用 icon 颜色
iconDisabledColor: Colors.redAccent.withOpacity(0.7),
// 启用 icon 颜色
iconEnabledColor: Colors.green.withOpacity(0.7),

  1. disabledHint 为禁用状态下默认展示内容,hint 为按钮启用状态下默认展示内容,采用 hintDropdownMenuItemtype 不为空,否则只会显示第一条 item
// 禁用默认内容
disabledHint: Text('暂不可用'),
// 启用默认内容
DropdownButton(icon: Icon(Icons.arrow_right), iconSize: 40, iconEnabledColor: Colors.green.withOpacity(0.7),
    hint: Text('请选择地区'),
    items: [
      DropdownMenuItem(child: Text('北京'), value: 1), DropdownMenuItem(child: Text('天津'), value: 2),
      DropdownMenuItem(child: Text('河北'), value: 3)
    ], onChanged: (value) {});
  1. underline 用来设置按钮下划线样式,若设置 null 显示的是高度为 1.0 的默认下划线样式,若需要隐藏下划线可以设置 Container 高度为 0.0
underline: Container(height: 4, color: Colors.green.withOpacity(0.7)),
// 隐藏下划线
underline: Container(height: 0),
  1. isDense 用来调整按钮高度,true 时将按钮高度缩小,缩小的高度通过 Theme _kDenseButtonHeight 决定,但不会缩小太多导致图标剪切;
// 源码
double get _denseButtonHeight {
    final double fontSize = _textStyle.fontSize ?? Theme.of(context).textTheme.subhead.fontSize;
    return math.max(fontSize, math.max(widget.iconSize, _kDenseButtonHeight));
}
  1. isExpanded 用于是否填充按钮宽度到父控件,true 为填充,false 为默认不填充;
// 源码
if (widget.isExpanded)
    Expanded(child: innerItemsWidget)
  1. elevationz 轴上垂直阴影,只能是 1 / 2 / 3 / 4 / 6 / 8 / 9 / 12 / 16 / 24,默认阴影高度是 8,若设置其他值不显示;
//源码
8: <BoxShadow>[
    BoxShadow(offset: Offset(0.0, 5.0), blurRadius: 5.0, spreadRadius: -3.0, color: _kKeyUmbraOpacity),
    BoxShadow(offset: Offset(0.0, 8.0), blurRadius: 10.0, spreadRadius: 1.0, color: _kKeyPenumbraOpacity),
    BoxShadow(offset: Offset(0.0, 3.0), blurRadius: 14.0, spreadRadius: 2.0, color: _kAmbientShadowOpacity),
],
  1. style 为下拉选项列表中文字样式;但下拉列表 item 设置文本样式后,以 item 设置为准;
DropdownButton(style: style,
    icon: Icon(Icons.arrow_right), iconSize: 40, iconEnabledColor: Colors.green.withOpacity(0.7),
    hint: Text('请选择地区'), isExpanded: true, underline: Container(height: 1, color: Colors.green.withOpacity(0.7)),
    items: [
      DropdownMenuItem(
          child: Row(children: <Widget>[Text('北京'), SizedBox(width: 10), Icon(Icons.ac_unit) ]),
          value: 1),
      DropdownMenuItem(
          child: Row(children: <Widget>[Text('天津'), SizedBox(width: 10), Icon(Icons.content_paste) ]),
          value: 2),
      DropdownMenuItem(
          child: Row(children: <Widget>[Text('河北', style: TextStyle(color: Colors.purpleAccent, fontSize: 16)), SizedBox(width: 10), Icon(Icons.send, color: Colors.purpleAccent) ]),
          value: 3)
    ],
    onChanged:(value) {});
  1. 对于 DropdownButton 选中回调,其中 itemsvalue 是必须参数,且不相同;回调返回的内容是 DropdownMenuItemchild 内容;
DropdownButton(
    value: _value, style: style,
    icon: Icon(Icons.arrow_right), iconSize: 40, iconEnabledColor: Colors.green.withOpacity(0.7),
    hint: Text('请选择地区'), isExpanded: true, underline: Container(height: 1, color: Colors.green.withOpacity(0.7)),
    items: [
      DropdownMenuItem(
          child: Row(children: <Widget>[Text('北京'), SizedBox(width: 10), Icon(Icons.ac_unit) ]),
          value: 1),
      DropdownMenuItem(
          child: Row(children: <Widget>[Text('天津'), SizedBox(width: 10), Icon(Icons.content_paste) ]),
          value: 2),
      DropdownMenuItem(
          child: Row(children: <Widget>[Text('河北', style: TextStyle(color: Colors.purpleAccent, fontSize: 16)), SizedBox(width: 10), Icon(Icons.send, color: Colors.purpleAccent) ]),
          value: 3)
    ],
    onChanged: (value) => setState(() => _value = value));

      DropdownButton 案例源码


      和尚对 DropdownButton 的尝试仅限于基本属性的应用,对于使用 PopupRoute 浮层展示 DropdownMenuItem 列表的源码层涉及较少;如有错误请多多指导!

来源: 阿策小和尚

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

推荐阅读更多精彩内容