【问题标题】:Flutter DropdownMenuItem in separate widget fileFlutter DropdownMenuItem 在单独的小部件文件中
【发布时间】:2020-09-16 02:15:04
【问题描述】:

我在 Flutter 中重构 DropdownButton 小部件的代码时遇到问题。我有简单的 DropdownButton。

DropdownButton(
  items: [
    DropdownMenuItem(
      child: Container(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Text('Ascending'),
            if (widget.currentDateSortOrder == SortOrderType.Ascending)
              Icon(Icons.check)
          ],
        ),
      ),
      value: 'Asc',
    ),
    DropdownMenuItem(
      child: Container(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Text('Descending'),
            if (widget.currentDateSortOrder == SortOrderType.Descending)
              Icon(Icons.check)
          ],
        ),
      ),
      value: 'Desc',
    )
  ],
  onChanged: (itemIdentifier) {
    ...
  },
)

我想将 DropdownMenuItem 移动到单独的小部件以使我的小部件树更精简。于是我把它搬走了。

import 'package:flutter/material.dart';

class FileListDropdownMenuItem extends StatelessWidget {
  final String labelText;
  final bool showSelectedMark;
  final String itemValue;

  FileListDropdownMenuItem(this.labelText, this.showSelectedMark, this.itemValue);

  @override
  Widget build(BuildContext context) {
    return DropdownMenuItem(
      child: Container(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Text(labelText),
            if (showSelectedMark)
              Icon(Icons.check)
          ],
        ),
      ),
      value: itemValue,
    );
  }
}

当我尝试像这样在 DropdownButton 中使用它时:

...
items: [
  FileListDropdownMenuItem(
      'Ascending',
      widget.currentDateSortOrder == SortOrderType.Ascending,
      'Asc')
],
...

我收到此错误:

The argument type 'List<FileListDropdownMenuItem>' can't be assigned to the parameter type 'List<DropdownMenuItem<dynamic>>'.

有没有办法让这种方法发挥作用?我知道我可以将 DropdownMenuItem 留在 DropdownButton 中,并将其仅“子”属性移动到单独的小部件。但是,我必须在主文件中管理 DropdownMenuItem 的“值”和其他属性。

【问题讨论】:

    标签: flutter dart dropdownbutton


    【解决方案1】:

    DropdownButton 要求其项目为 List&lt;DropdownMenuItem&gt;。但是您的课程FileListDropdownMenuItem 仅扩展了StatelessWidget。如果你想用它代替DropdownMenuItem,你应该扩展它:

    class FileListDropdownMenuItem extends DropdownMenuItem {
      FileListDropdownMenuItem(
        String labelText,
        bool showSelectedMark,
        String itemValue,
      ) : super(
        child: Container(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Text(labelText),
              if (showSelectedMark)
                Icon(Icons.check)
            ],
          ),
        ),
        value: itemValue,
      );
    }
    

    【讨论】:

    • 谢谢。不通过构建方法而是通过构造函数来定义这个类是一个不错的选择。顺便说一句,在 FileListDropdownMenuItem 的构建方法中,我返回了一个 DropdownMenuItem。所以我认为最后会有一个 DropdownMenuItem 对象在我调用 FileListDropdownMenuItem 的构造函数的地方。还是会有 FileListDropdownMenuItem 对象?
    • DropdownButton 要求项目是 List 因为它使用 DropdownMenuItem 的字段(onTap 和 value)。但是,在编译时,DropdownButton 不知道您将在 build.xml 中返回 DropdownMenuItem。它只知道你会返回一些 Widget 子类。此外,即使您返回 DropdownMenuItem,它也会与您的 FileListDropdownMenuItem 一起包装在小部件树中。所以 DropdownButton 小部件不能直接访问 DropdownMenuItem 对象
    • 相反,如果您扩展 DropdownMenuItem 并将 child/value/onTap 传递给 super 的构造函数,则编译时保证 FileListDropdownMenuItem 会将它们作为字段。例如,这将是有效的:var d = FileListDropdownMenuItem(...);d.onTapd.childd.value
    • 感谢您的解释。我猜这是行为。
    猜你喜欢
    • 2022-06-18
    • 2021-08-04
    • 2019-09-26
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多