和尚对于 Flutter 并不系统,总是遇到问题才会准备尝试,今天和尚准备学习一下下拉选择框;Android 提供了便利的 Spinner 而 Flutter 对应的是 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 内容
})
分析源码可知,items 和 onChanged 回调是必须参数,且在不同状态下,展示的效果不同;其中 items 或 onChanged 为 null 时为禁用状态,和尚接下来逐一分析各属性;
DropdownButton(items: null, onChanged: null);
DropdownButton(items: [
DropdownMenuItem(child: Text('北京')),
DropdownMenuItem(child: Text('天津')),
DropdownMenuItem(child: Text('河北'))
], onChanged: (value) {});
icon: Icon(Icons.arrow_right),
// icon: Icon(Icons.arrow_right, color: Colors.blue.withOpacity(0.7), size: 60),
iconSize: 40,
// 禁用 icon 颜色
iconDisabledColor: Colors.redAccent.withOpacity(0.7),
// 启用 icon 颜色
iconEnabledColor: Colors.green.withOpacity(0.7),
// 禁用默认内容
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) {});
underline: Container(height: 4, color: Colors.green.withOpacity(0.7)),
// 隐藏下划线
underline: Container(height: 0),
// 源码
double get _denseButtonHeight {
final double fontSize = _textStyle.fontSize ?? Theme.of(context).textTheme.subhead.fontSize;
return math.max(fontSize, math.max(widget.iconSize, _kDenseButtonHeight));
}
// 源码
if (widget.isExpanded)
Expanded(child: innerItemsWidget)
//源码
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),
],
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) {});
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 列表的源码层涉及较少;如有错误请多多指导!