Drop down menu 如何在Flatter中创建自定义下拉列表?

Drop down menu 如何在Flatter中创建自定义下拉列表?,drop-down-menu,widget,flutter,Drop Down Menu,Widget,Flutter,我仍在学习颤振,我正在尝试创建一个自定义下拉列表。下面是我的自定义下拉列表,它似乎可以工作并返回所选的值,但我仍然需要有关如何在按下墨水池时显示弹出列表的帮助。另外,如何传入字符串数组以构建/填充弹出列表项。谢谢你在这方面的帮助 return new Expanded( flex: 4, child: new InputDropdownList( labelText: "Select a value", valueText: viewModel.selec

我仍在学习颤振,我正在尝试创建一个自定义下拉列表。下面是我的自定义下拉列表,它似乎可以工作并返回所选的值,但我仍然需要有关如何在按下墨水池时显示弹出列表的帮助。另外,如何传入字符串数组以构建/填充弹出列表项。谢谢你在这方面的帮助

return new Expanded(
    flex: 4,
    child: new InputDropdownList(
      labelText: "Select a value",
      valueText: viewModel.selectedValue,
      valueStyle: Theme.of(context).inputDecorationTheme.labelStyle,
      items: <String>["ValueA", "ValueB", "ValueC", "ValueD"],
      onPressed: () { 
      },
      selectedValue: (String value) { 
        setState(() { viewModel.selectedValue= value; });
      },
    ),
),


class InputDropdownList extends StatelessWidget {
  const _InputDropdownList({
    Key key,
    this.labelText,
    this.valueText,
    this.valueStyle,
    this.items,
    this.onPressed,
    this.selectedValue }) : super(key: key);

  final String labelText;
  final String valueText;
  final TextStyle valueStyle;
  final List<String> items;
  final Function() onPressed;
  final ValueChanged<String> selectedValue;

  @override
  Widget build(BuildContext context) {
    return new InkWell(
      onTap: () {},
      child: new InputDecorator(
        decoration: new InputDecoration(
          labelText: labelText,
        ),
        baseStyle: valueStyle,
        child: new Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            new Text(valueText, style: valueStyle),
            new PopupMenuButton<String>(
              icon: new Icon(Icons.arrow_drop_down, color: Theme.of(context).brightness == Brightness.light ? Colors.grey.shade700 : Colors.white70),
              padding: EdgeInsets.zero,
              onSelected: (value) {
                selectedValue(value);
              },
              itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
                new PopupMenuItem<String>(
                  value: "ValueA",
                  child: const Text('ValueA')
                ),
                new PopupMenuItem<String>(
                  value: "ValueB",
                  child: const Text('ValueB')
                ),
              ]
            ),
          ],
        ),
      ),
    );
  }
}
返回新扩展的(
弹性:4,
子项:新的InputDropdownList(
labelText:“选择一个值”,
valueText:viewModel.selectedValue,
valueStyle:Theme.of(context).inputDecorationTheme.labelStyle,
项目:[“价值A”、“价值B”、“价值C”、“价值”],
onPressed:(){
},
selectedValue:(字符串值){
setState((){viewModel.selectedValue=value;});
},
),
),
类InputDropdownList扩展了无状态小部件{
常量输入下拉列表({
关键点,
这是labelText,
这篇文章,
这是我的风格,
这个项目,,
这是一个非常紧迫的问题,
this.selectedValue}):超级(key:key);
最终字符串标签文本;
最终字符串值文本;
最终文本样式值样式;
最后清单项目;
final Function()已按下;
最终值更改选定值;
@凌驾
小部件构建(构建上下文){
返回新墨水池(
onTap:(){},
子:新输入装饰器(
装饰:新的输入装饰(
labelText:labelText,
),
baseStyle:valueStyle,
孩子:新的一排(
mainAxisAlignment:mainAxisAlignment.spaceBetween,
mainAxisSize:mainAxisSize.min,
儿童:[
新文本(valueText,样式:valueStyle),
新弹出菜单按钮(
图标:新图标(Icons.arrow\u下拉菜单,颜色:Theme.of(context.brightness==brightness.light?Colors.grey.shade700:Colors.white70),
填充:EdgeInsets.zero,
onSelected:(值){
选择值(value);
},
itemBuilder:(构建上下文)=>[
新PopupMenuItem(
价值:“价值A”,
子项:常量文本('ValueA')
),
新PopupMenuItem(
值:“ValueB”,
子项:常量文本('ValueB')
),
]
),
],
),
),
);
}
}

所以这里有两个问题:您想使用
列表来填充
弹出菜单按钮
,而单击
墨水池
不会打开弹出菜单

对于第一个问题,可以创建一个用于生成PopupMenuItem列表的函数,以便在PopupMenuButton itemBuilder上进行设置

\u popupMenuItems(){
var popupMenuItemList=[];
items.forEach((itemValue){
popupMenuItemList.add(
PopupMenuItem(值:itemValue,子项:文本(“$itemValue”);
});
返回popupMenuItemList;
}
在PopupMenuButton itemBuilder中设置
\u popupMenuItems()

弹出菜单按钮(
...
itemBuilder:(BuildContext上下文)=>\u popupMenuItems(),
);
至于第二个问题,您给出的示例中的当前设置基础将
InkWell
作为父窗口小部件。只有单击
PopupMenuButton
时,才能显示弹出菜单。使用这种方法,
PopupMenuButton
只能在小部件的一小部分上单击

InkWell(
子:输入装饰器(
孩子:排(
儿童:[
Text(),
PopupMenuButton(),
],
),
),
)
作为解决方案,
PopupMenuButton
可以是InkWell的父窗口小部件。这样,单击PopupMenuButton中的子项仍应显示弹出菜单

弹出菜单按钮(
孩子:InkWell(
子:输入装饰器(
孩子:排(
儿童:[
Text(),
图标(),
],
),
),
),
)
请注意,您只能在
PopupMenuButton
中使用
child
icon
,而不能同时使用两者。由于无法使用
图标
,我们可以在
文本
旁边设置
图标

这是一个完整的工作样本

导入“包装:颤振/材料.省道”;
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
//此小部件是应用程序的根。
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
var selectedValue=‘默认值’;
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(widget.title),
),
正文:中(
子项:InputDropdownList(
labelText:“选择一个值”,
valueText:selectedValue,
valueStyle:Theme.of(context).inputDecorationTheme.labelStyle,
项目:[“价值A”、“价值B”、“价值C”、“价值”],
按下:(){},
selectedValue:(字符串值){
设置状态(){
selectedValue=值;
});
},
),
), 
);
}
}
类InputDropdownList扩展了无状态小部件{
常量输入下拉列表(
{键,
这是labelText,
这篇文章,
这是我的风格,
这个项目,,
这是一个非常紧迫的问题,
此参数为.selectedValue})
:super(key:key);
最终字符串标签文本;
最终字符串值文本;
最终文本样式值样式;
最后清单项目;
final Function()已按下;
最终值更改选定值;
_popupMenuItems(){
var popupMenuItemList=[];
items.forEach((itemValue){
打印(“$itemValue”);
po
Here is the dropdown with custom UI,
List<String> slots = [
    '1',
    '2',
    '3',
    '4',
    '5',
];

    List<DropdownMenuItem<String>> mItems = new List();
    
        for (int i = 0; i < slots.length; i++) {
          mItems.add(new DropdownMenuItem(
            child: new Text(slots[i]),
            value: slots[i],
          ));
        }
    

    Container(
    height: 50,
    padding: EdgeInsets.only(left: 10, right: 10),
    margin: EdgeInsets.only(
    bottom: 20, left: 15, right: 15),
    alignment: Alignment.center,
        decoration: BoxDecoration(
        color: Colors.grey,
        borderRadius: const BorderRadius.all(
        const Radius.circular(12.0),
        ),
        ),
        child: DropdownButton(
        isExpanded: true,
        underline: Container(),
        icon: Icon(
        Icons.keyboard_arrow_down,
        color: textBlue,
        ),
        hint: Text(
        value,
        style: kTextFieldStyleFill,
        ),
        value: value,
        onChanged: (newValue) {
        setState(() {
        value = newValue;
        });
        },
        items: mItems,
        ),
    )