在Flutter中创建下拉菜单

时间:2019-10-07 05:40:56

标签: flutter dart drop-down-menu

我想在我的应用中执行的操作是基于列表内容添加一个下拉列表。我有这样的东西:

df1 = df.select_dtypes(np.number)
c = df1.columns[np.any(np.isclose(df1, 100), axis=0)].tolist()
print (c)
[]

print (next(iter(c), 'no match'))
no match

当前有2个条目。我想做的是显示一个包含这些选项([ { 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} ] } ] Enter value)的下拉列表,作为下拉列表的2个条目:

  • 如果选择了Source,则应显示其旁边的文本框,因为它的类型为Enter value
  • 如果在下拉菜单中选择了string选项,则包含这些条目(SourceMOAO)的另一个下拉菜单应显示为下拉值,因为它具有一个列表类型。

简而言之,应根据对第一个下拉菜单的选择,选择要显示的小部件(文本框或另一个下拉菜单)。

如果有人知道或以前做过同样的事情,请帮助我,谢谢。

1 个答案:

答案 0 :(得分:0)

我将使用StatefulWidget来实现所需的功能(如果您不使用更高级的状态管理选项)。状态将有助于跟踪用户的选择,并决定是呈现文本字段还是其他下拉列表(或完全不显示任何内容)。

我在下面添加了一个完整的工作示例。请注意,在某种意义上说,它不遵循最佳实践,您可能希望将其拆分为单独的小部件,以提高组合性(和可读性)。但是,我选择了一种快速实用的方法来将所有内容都放在一个地方。

还要注意,一旦用户做出选择,您可能希望做更多的处理。在这里,我仅说明如何根据用户的选择(或更一般而言,StatefulWidget's状态的变化)呈现不同的小部件。因此,此示例仅用于强调一个原理。

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;

  final items = [
    {
      "displayName": "Enter value",
      "type": "string",
    },
    {
      "displayName": "Source",
      "type": "list",
      "data": [
        {"id": 1, "displayId": "MO"},
        {"id": 2, "displayId": "AO"},
        {"id": 3, "displayId": "OffNet"}
      ]
    }
  ];

  @override
  Widget build(BuildContext context) {
    Widget supporting = buildSupportingWidget();

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Dropdown Example")),
        body: Center(
          child: Container(
            height: 600,
            width: 300,
            child: Row(
              children: <Widget>[
                buildMainDropdown(),
                if (supporting != null) supporting,
              ],
            ),
          ),
        ),
      ),
    );
  }

  Expanded buildMainDropdown() {
    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() {
    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;
  }