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;
  }
}