【问题标题】:Creating a Dropdown menu in Flutter在 Flutter 中创建下拉菜单
【发布时间】:2019-10-07 05:40:56
【问题描述】:

我想要在我的应用程序中做的是根据列表内容添加一个下拉列表。我有这样的事情:

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

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

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

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

【问题讨论】:

标签: flutter dart drop-down-menu


【解决方案1】:

我会使用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;
  }

【讨论】:

  • 感谢您的帮助,知道了如何实现这样的东西。但是如果它必须显示在底部表中,那么每当状态由于下拉菜单的更改而发生变化时,因为它没有在底部表中更新
  • 看起来需要将状态传播到底部工作表,以便对其做出反应。但是,我有点犹豫要不要说这是没有看到代码的解决方案。我建议为这个特定问题创建另一个问题(带有示例代码)。
  • 如果项目 List 发生了变化,我得到了异常,并且项目列表没有固定它可能包含尽可能多的文本以及 Lists ,所以在选择它的抛出异常后的第一个下拉列表中
  • 如果我在列表中再添加一个 { "displayName": "Enter valuea", "type": "string", } 或 A list like this { "id": "si ", "displayName": "Source", "type": "list", "value": ["MO"], "searchField": "si", "data": [ {"id": 1, "displayId ": "MO"}, {"id": 2, "displayId": "AO"}, {"id": 3, "displayId": "OffNet"} ] } 我遇到异常
  • 这是意料之中的。答案中的代码示例仅考虑原始问题中的数据。您必须对其进行调整以确保它不依赖于项目数量或其顺序(示例)或重复类型。我建议阅读以下主题以了解DropdownButton 的局限性:How to implement drop down list in flutter?。看看它是否适用于您的情况,如果不适用 - 请考虑发布一个新问题,其中包含您收到的错误和您正在传递的数据。
猜你喜欢
  • 2020-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-20
  • 2015-12-07
相关资源
最近更新 更多