如何在 Flutter 中使用对象创建下拉菜单

Flo*_*scu 3 dart flutter

我尝试创建一个下拉列表并用几个对象填充它,这些对象代表用户可以从中选择一个的服务器,但是当我运行该应用程序时,我收到一条错误消息:

\n

The following assertion was thrown building DropdownWidget(dirty, state: _DropdownWidgetState#1f58f): There should be exactly one item with [DropdownButton]'s value: Instance of 'ServerModel'. Either zero or 2 or more [DropdownMenuItem]s were detected with the same value

\n

您能帮我找出我的代码中做错了什么吗?

\n
import 'package:flutter/material.dart';\n\xe2\x80\x8b\nclass ServerSettingsPage extends StatefulWidget {\n  @override\n  _ServerSettingsPageState createState() => _ServerSettingsPageState();\n}\n\xe2\x80\x8b\nclass _ServerSettingsPageState extends State<ServerSettingsPage> {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n      title: Text("Server Settings")),\n      body: _buildUI(),\n    );\n  }\n\xe2\x80\x8b\n  Widget _buildUI() {\n    return Padding(\n      padding: const EdgeInsets.fromLTRB(0, 20, 0, 0),\n      child: Center(\n        child: Column(\n          children: <Widget>[\n            Text(\n              'Select a server:',\n              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),\n            ),\n            DropdownWidget(),\n          ],\n        ),\n      ),\n    );\n  }\n}\n\xe2\x80\x8b\nclass DropdownWidget extends StatefulWidget {\n  DropdownWidget({Key key}) : super(key: key);\n\xe2\x80\x8b\n  @override\n  _DropdownWidgetState createState() => _DropdownWidgetState();\n}\n\xe2\x80\x8b\nclass _DropdownWidgetState extends State<DropdownWidget> {\n  ServerModel dropdownValue =\n      ServerModel(name: 'Default', url: 'https://defaultServer.com/');\n\xe2\x80\x8b\n  @override\n  Widget build(BuildContext context) {\n    return DropdownButton<ServerModel>(\n      value: dropdownValue,\n      icon: Icon(Icons.arrow_downward),\n      iconSize: 24,\n      elevation: 16,\n      style: TextStyle(color: Colors.purple[700]),\n      underline: Container(\n        height: 2,\n        color: Colors.purple[700],\n      ),\n      onChanged: (ServerModel newServer) {\n        setState(() {\n          dropdownValue = newServer;\n        });\n      },\n      items: <ServerModel>[\n        ServerModel(name: 'Default', url: 'https:defaultServer.com/'),\n        ServerModel(name: 'Alpha', url: 'https://alphaServer.com/'),\n        ServerModel(name: 'Beta', url: 'https://betaServer.com/'),\n      ].map<DropdownMenuItem<ServerModel>>((ServerModel server) {\n        return DropdownMenuItem<ServerModel>(\n          value: server,\n          child: Text(server.name, style: TextStyle(fontSize: 20)),\n        );\n      }).toList(),\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是 ServerModel 类:

\n
class ServerModel {\n  ServerModel({this.name, this.url});\n\xe2\x80\x8b\n  ServerModel.empty() {\n    this.name = null;\n    this.url = null;\n  }\n\xe2\x80\x8b\n  String name;\n  String url;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

非常感谢您阅读这篇文章。

\n

Uro*_*roš 7

应该只有一项具有 [DropdownButton] 的值:“ServerModel”的实例。检测到零个或 2 个或多个 [DropdownMenuItem] 具有相同的值

发生这种情况是因为下拉列表中的选定值必须指向现有的列表项(显然该列表中不应该有任何重复项)。您现在设置的方式是,ServerModel 列表是在小部件构建期间生成的,一旦构建完成,就不会引用小部件状态内的列表。我希望我的答案足够清楚,也看看下面的正确代码:

class _DropdownWidgetState extends State<DropdownWidget> {
  List<ServerModel> serverModels = <ServerModel>[
    ServerModel(name: 'Default', url: 'https:defaultServer.com/'),
    ServerModel(name: 'Alpha', url: 'https://alphaServer.com/'),
    ServerModel(name: 'Beta', url: 'https://betaServer.com/'),
  ];
  ServerModel selectedServer;

  @override
  initState() {
    super.initState();
    selectedServer = serverModels[0];
  }

  @override
  Widget build(BuildContext context) {
    return DropdownButton<ServerModel>(
      value: selectedServer,
      icon: Icon(Icons.arrow_downward),
      iconSize: 24,
      elevation: 16,
      style: TextStyle(color: Colors.purple[700]),
      underline: Container(
        height: 2,
        color: Colors.purple[700],
      ),
      onChanged: (ServerModel newServer) {
        setState(() {
          selectedServer = newServer;
        });
      },
      items: serverModels.map((ServerModel map) {
        return new DropdownMenuItem<ServerModel>(
            value: map, child: Text(map.name));
      }).toList(),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在 dartpad 上经过测试、有效的交互式答案: https://dartpad.dev/153bad9baac64382e27bc41cdc8131c9