如何制作自定义下拉菜单



如何在不更改下拉按钮宽度的情况下更改下拉菜单的宽度和高度?当按下DropdownButton时,我需要DropdownMenu填充整个屏幕。如何更改下拉菜单的位置,使其显示在按钮下方,但不与按钮重叠?

String dropdownValue = '1';
Widget build(BuildContext context) {
return MaterialApp(
theme: new ThemeData(
brightness: Brightness.light,
primaryColor: Color...,
accentColor: Colors...,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
actions: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(0.0, 5.0, 265.0, 0.0),
child: CustomDropdownButton<String>(
value: dropdownValue,
icon:
Icon(Icons.arrow_drop_down, color: Colors...),
iconSize: 21,
elevation: 16,
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.w600),
underline: Container(
width: 200,
height: 2,
color: Colors...,
),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items: <String>[
'1',
'2',
'3',
'4'
].map<CustomDropdownMenuItem<String>>((String value) {
return CustomDropdownMenuItem<String>(
child: SizedBox(
width: 120.0,
child: Text("  " + value),
),
value: value,
);
}).toList(), ),)... 

使用DropdownButtonDropdownMenuItem不可能做到这一点,但使用offset属性使用PopupMenuButtonPopupMenuItem可以实现这一点。

下面是一个如何做到这一点的快速示例:

final _itemHeight = 80.0;
final _buttonHeight = 100.0;
final _values = [1, 2, 3, 4];
var _selectedValue = 1;
Offset _buildOffset() => Offset(
0, _buttonHeight * 2 + _values.indexOf(_selectedValue) * _itemHeight * 2);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: PopupMenuButton(
child: Container(
color: Colors.yellow,
height: _buttonHeight,
width: 100,
child: Center(child: Text('Item $_selectedValue'))),
onSelected: (value) => setState(() => _selectedValue = value),
initialValue: _selectedValue,
offset: _buildOffset(),
itemBuilder: (context) => _values
.map((i) => PopupMenuItem(
height: _itemHeight,
child: Text('Item $i'),
value: i,
))
.toList(),
),
);
}

编辑:不幸的是,即使用SizedBox包裹PopupMenuItem的子级并设置width来填充屏幕宽度,它也不会工作,因为PopupMenuItemmaxWidth(_kMenuMaxWidth(。

以下是使用AnimatedContainer:制作类似内容的方法

final _itemHeight = 80.0;
final _values = [1, 2, 3, 4];
var _selectedValue = 1;
var _expanded = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: <Widget>[
InkWell(
child: Container(
height: 100,
width: 100,
color: Colors.yellow,
child: Text('Item $_selectedValue'),
),
onTap: () => setState(() => _expanded = !_expanded),
),
AnimatedContainer(
duration: Duration(milliseconds: 250),
height: _expanded ? _itemHeight * _values.length : 0,
child: ListView(
primary: false,
children: _values
.map(
(value) => SizedBox(
width: MediaQuery.of(context).size.width,
height: _itemHeight,
child: Material(
color: Colors.white,
child: InkWell(
child: Text('Item $value'),
onTap: () => setState(
() {
_selectedValue = value;
_expanded = false;
},
),
),
),
),
)
.toList(),
),
),
],
),
);
}

最新更新