Flutter 在Flatter中的底部板材内创建下拉菜单
我正在尝试这样做,根据列表内容创建一个下拉列表。 我的清单是这样的Flutter 在Flatter中的底部板材内创建下拉菜单,flutter,dart,drop-down-menu,bottom-sheet,Flutter,Dart,Drop Down Menu,Bottom Sheet,我正在尝试这样做,根据列表内容创建一个下拉列表。 我的清单是这样的 [ { id: val, displayName: Enter value, type: string, value: "any" }, { id: si, displayName: Source, type: list, value: [ MO
[
{
id: val,
displayName: Enter value,
type: string,
value: "any"
},
{
id: si,
displayName: Source,
type: list,
value: [
MO
],
data: [
{id: 1, displayId: MO},
{id: 2, displayId: AO},
{id: 3, displayId: OffNet}
]
}
]
目前有2个条目。将包含这些选项(输入值和源)的下拉列表显示为下拉列表的两个条目
如果选择了“输入值”,则应在其旁边显示一个文本框,因为它具有字符串类型。
如果选择了下拉列表中的源选项,则包含这些条目(MO、AO、Offnet)的另一个下拉列表应作为下拉列表值显示,因为它具有列表类型
根据第一个下拉列表的选择,应选择要显示的小部件(文本框或其他下拉列表)
我有一个这样的代码,它会做必要的事情,但是这里把整个页面作为一个容器,每当选项改变一个setState调用,它会重建build方法,但是我想在底部实现同样的事情,我不知道如何管理状态,也就是说,一旦下拉列表中的选项发生更改,我希望底部工作表使用数据进行重建
代码:
导入“包装:颤振/材料.省道”;
void main(){
runApp(DropdownExample());
}
类DropdownExample扩展StatefulWidget{
@凌驾
_DropdownExampleState createState()=>\u DropdownExampleState();
}
类\u DropdownExampleState扩展状态{
字符串类型;
int optionId;
最后项目=[
{
“displayName”:“输入值”,
“类型”:“字符串”,
},
{
“显示名称”:“源”,
“类型”:“列表”,
“数据”:[
{“id”:1,“displayId”:“MO”},
{“id”:2,“displayId”:“AO”},
{“id”:3,“displayId”:“OffNet”}
]
}
];
@凌驾
小部件构建(构建上下文){
Widget supporting=buildSupportingWidget();
返回材料PP(
家:脚手架(
appBar:appBar(标题:文本(“下拉示例”),
正文:中(
子:容器(
身高:600,
宽度:300,
孩子:排(
儿童:[
BuildMain下拉列表(),
如果(支持!=null)支持,
],
),
),
),
),
);
}
扩展的BuildMain下拉列表(){
扩大回报(
子项:DropdownButtonHideUnderline(
孩子:下拉按钮(
值:类型,
提示:文本(“选择类型”),
项目:项目
.map((json)=>DropdownMenuItem(
子项:文本(json[“displayName”]),值:json[“type”])
.toList(),
一旦更改:(新类型){
设置状态(){
类型=新类型;
});
},
),
),
);
}
Widget buildSupportingWidget(){
如果(类型=“列表”){
列表选项=项目[1][“数据”];
扩大回报(
子项:DropdownButtonHideUnderline(
孩子:下拉按钮(
值:optionId,
提示:文本(“选择条目”),
项目:选项
.map((选项)=>DropdownMenuItem(
子项:文本(选项[“displayId”]),值:选项[“id”])
.toList(),
一旦更改:(newId)=>setState(){
this.optionId=newId;
}),
),
),
);
}else if(类型==“字符串”){
返回已展开(子项:TextFormField());
}
返回null;
}
}
上面的代码工作得很好,但我正在尝试做的是,同样的事情应该包含在具有确切功能的底稿中
每当按下“打开底页”按钮时,应弹出底页,并将代码结果显示为底页的内容
我做过类似的事情,但它不起作用
import 'package:flutter/material.dart';
void main() {
runApp(DropdownExample());
}
class DropdownExample extends StatefulWidget {
@override
_DropdownExampleState createState() => _DropdownExampleState();
}
class _DropdownExampleState extends State<DropdownExample> {
String type;
int optionId;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("Dropdown Example")),
body: Center(
child: Container(
height: 600,
width: 300,
child: Row(
children: <Widget>[
Align(
alignment: Alignment.topRight,
child: FlatButton.icon(
label: Text('Filters'),
icon: Icon(Icons.filter_list),
onPressed: showModalSheet(),
)),
],
),
),
),
),
);
}
showModalSheet() {
final items = [
{
"displayName": "Enter value",
"type": "string",
},
{
"displayName": "Source",
"type": "list",
"data": [
{"id": 1, "displayId": "MO"},
{"id": 2, "displayId": "AO"},
{"id": 3, "displayId": "OffNet"}
]
}
];
showModalBottomSheet<void>(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter state) {
return createBox(context, items, state);
});
});
}
createBox(BuildContext context, List<Map<String,Object>> val,StateSetter state) {
Widget supporting = buildSupportingWidget(val);
return SingleChildScrollView(
child: LimitedBox(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
buildMainDropdown(val),
if (supporting != null) supporting
]
)
)
);
}
Expanded buildMainDropdown(List<Map<String,Object>> items) {
return Expanded(
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: type,
hint: Text("Select a type"),
items: items
.map((json) => DropdownMenuItem(
child: Text(json["displayName"]), value: json["type"]))
.toList(),
onChanged: (newType) {
setState(() {
type = newType;
});
},
),
),
);
}
Widget buildSupportingWidget(List<Map<String,Object>>items) {
if (type == "list") {
List<Map<String, Object>> options = items[1]["data"];
return Expanded(
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: optionId,
hint: Text("Select an entry"),
items: options
.map((option) => DropdownMenuItem(
child: Text(option["displayId"]), value: option["id"]))
.toList(),
onChanged: (newId) => setState(() {
this.optionId = newId;
}),
),
),
);
} else if (type == "string") {
return Expanded(child: TextFormField());
}
return null;
}
}
导入“包装:颤振/材料.省道”;
void main(){
runApp(DropdownExample());
}
类DropdownExample扩展StatefulWidget{
@凌驾
_DropdownExampleState createState()=>\u DropdownExampleState();
}
类\u DropdownExampleState扩展状态{
字符串类型;
int optionId;
@凌驾
小部件构建(构建上下文){
返回材料PP(
家:脚手架(
appBar:appBar(标题:文本(“下拉示例”),
正文:中(
子:容器(
身高:600,
宽度:300,
孩子:排(
儿童:[
对齐(
对齐:alignment.topRight,
子:FlatButton.icon(
标签:文本(“过滤器”),
图标:图标(图标。过滤器列表),
onPressed:showModalSheet(),
)),
],
),
),
),
),
);
}
showModalSheet(){
最后项目=[
{
“displayName”:“输入值”,
“类型”:“字符串”,
},
{
“显示名称”:“源”,
“类型”:“列表”,
“数据”:[
{“id”:1,“displayId”:“MO”},
{“id”:2,“displayId”:“AO”},
{“id”:3,“displayId”:“OffNet”}
]
}
];
showModalBottomSheet(
形状:圆形矩形边框(
边界半径:边界半径。圆形(10.0),
),
上下文:上下文,
生成器:(BuildContext上下文){
返回状态生成器(
生成器:(BuildContext上下文,StateSetter状态){
返回createBox(上下文、项、状态);
});
});
}
createBox(BuildContext上下文、列表值、StateSetter状态){
Widget supporting=buildSupportingWidget(val);
返回SingleChildScrollView(
孩子:LimitedBox(
子:列(
mainAxisSize:mainAxisSize.max,
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
BuildMain下拉列表(val),
如果(支持!=null)支持
]
)
)
);
}
扩展的BuildMain下拉列表(列表项){
扩大回报(
儿童:下拉按钮HideUnderli
import 'package:flutter/material.dart';
void main() {
runApp(DropdownExample());
}
class DropdownExample extends StatefulWidget {
@override
_DropdownExampleState createState() => _DropdownExampleState();
}
class _DropdownExampleState extends State<DropdownExample> {
String type;
int optionId;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("Dropdown Example")),
body: Center(
child: Container(
height: 600,
width: 300,
child: Row(
children: <Widget>[
Align(
alignment: Alignment.topRight,
child: FlatButton.icon(
label: Text('Filters'),
icon: Icon(Icons.filter_list),
onPressed: showModalSheet(),
)),
],
),
),
),
),
);
}
showModalSheet() {
final items = [
{
"displayName": "Enter value",
"type": "string",
},
{
"displayName": "Source",
"type": "list",
"data": [
{"id": 1, "displayId": "MO"},
{"id": 2, "displayId": "AO"},
{"id": 3, "displayId": "OffNet"}
]
}
];
showModalBottomSheet<void>(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter state) {
return createBox(context, items, state);
});
});
}
createBox(BuildContext context, List<Map<String,Object>> val,StateSetter state) {
Widget supporting = buildSupportingWidget(val);
return SingleChildScrollView(
child: LimitedBox(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
buildMainDropdown(val),
if (supporting != null) supporting
]
)
)
);
}
Expanded buildMainDropdown(List<Map<String,Object>> items) {
return Expanded(
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: type,
hint: Text("Select a type"),
items: items
.map((json) => DropdownMenuItem(
child: Text(json["displayName"]), value: json["type"]))
.toList(),
onChanged: (newType) {
setState(() {
type = newType;
});
},
),
),
);
}
Widget buildSupportingWidget(List<Map<String,Object>>items) {
if (type == "list") {
List<Map<String, Object>> options = items[1]["data"];
return Expanded(
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: optionId,
hint: Text("Select an entry"),
items: options
.map((option) => DropdownMenuItem(
child: Text(option["displayId"]), value: option["id"]))
.toList(),
onChanged: (newId) => setState(() {
this.optionId = newId;
}),
),
),
);
} else if (type == "string") {
return Expanded(child: TextFormField());
}
return null;
}
}
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: DropdownExample(),
);
}
}
class DropdownExample extends StatefulWidget {
@override
_DropdownExampleState createState() => _DropdownExampleState();
}
class _DropdownExampleState extends State<DropdownExample> {
String type;
int optionId;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("Dropdown Example")),
body: Center(
child: Container(
height: 600,
width: 300,
child: Row(
children: <Widget>[
Align(
alignment: Alignment.topRight,
child: FlatButton.icon(
label: Text('Filters'),
icon: Icon(Icons.filter_list),
// onPressed: showModalSheet(),
onPressed: () {
showModalSheet(context);
},
)),
],
),
),
),
),
);
}
void showModalSheet(BuildContext context) {
final items = [
{
"displayName": "Enter value",
"type": "string",
},
{
"displayName": "Source",
"type": "list",
"data": [
{"id": 1, "displayId": "MO"},
{"id": 2, "displayId": "AO"},
{"id": 3, "displayId": "OffNet"}
]
}
];
showModalBottomSheet<void>(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter state) {
return createBox(context, items, state);
});
});
}
createBox(BuildContext context, List<Map<String,Object>> val,StateSetter state) {
Widget supporting = buildSupportingWidget(val,state);
return SingleChildScrollView(
child: LimitedBox(
maxHeight: 300,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
buildMainDropdown(val,state),
if (supporting != null) supporting
]
)
)
);
}
Expanded buildMainDropdown(List<Map<String,Object>> items,StateSetter setState) {
return Expanded(
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: type,
hint: Text("Select a type"),
items: items
.map((json) => DropdownMenuItem(
child: Text(json["displayName"]), value: json["type"]))
.toList(),
onChanged: (newType) {
setState(() {
type = newType;
});
},
),
),
);
}
Widget buildSupportingWidget(List<Map<String,Object>>items, StateSetter setState) {
if (type == "list") {
List<Map<String, Object>> options = items[1]["data"];
return Expanded(
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: optionId,
hint: Text("Select an entry"),
items: options
.map((option) => DropdownMenuItem(
child: Text(option["displayId"]), value: option["id"]))
.toList(),
onChanged: (newId) => setState(() {
this.optionId = newId;
}),
),
),
);
} else if (type == "string") {
return Expanded(child: TextFormField());
}
return null;
}
}