简体   繁体   English

如何使小部件在 Flutter 中可重用?

[英]How do I make widgets reusable in Flutter?

I'm attempting to use the Flutter DropdownMenu with different parameters on the same page, however I'm unsure how to structure the code.我试图在同一页面上使用具有不同参数的 Flutter DropdownMenu ,但是我不确定如何构建代码。

If I want to use a list other than ['One', 'Two', 'Free', 'Four'] how would I setup the widget to take different parameters without having to copy and paste the widget everytime?如果我想使用除['One', 'Two', 'Free', 'Four']我将如何设置小部件以采用不同的参数,而不必每次都复制和粘贴小部件?

This is the sample code from the docs:这是文档中的示例代码:

String dropdownValue = 'One';

@override
Widget build(BuildContext context) {
  return DropdownButton<String>(
    value: dropdownValue,
    icon: Icon(Icons.arrow_downward),
    iconSize: 24,
    elevation: 16,
    style: TextStyle(
      color: Colors.deepPurple
    ),
    underline: Container(
      height: 2,
      color: Colors.deepPurpleAccent,
    ),
    onChanged: (String newValue) {
      setState(() {
        dropdownValue = newValue;
      });
    },
    items: <String>['One', 'Two', 'Free', 'Four']
      .map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      })
      .toList(),
  );
}

Create a method that returns a DropdownButton .创建一个返回DropdownButton的方法。

  Widget createDropdownButton({
    String value,
    List<String> items,
    ValueChanged<String> onChanged,
  }) {
    return DropdownButton<String>(
      value: value,
      icon: Icon(Icons.arrow_downward),
      iconSize: 24,
      elevation: 16,
      style: TextStyle(color: Colors.deepPurple),
      underline: Container(
        height: 2,
        color: Colors.deepPurpleAccent,
      ),
      onChanged: onChanged,
      items: items.map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),
    );
  }
  String dropdownValue1 = 'Two';
  String dropdownValue2 = '3';

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      createDropdownButton(
          value: dropdownValue1,
          items: ['One', 'Two', 'Free', 'Four'],
          onChanged: (String newValue) {
            setState(() {
              dropdownValue1 = newValue;
            });
          }),
      createDropdownButton(
          value: dropdownValue2,
          items: ['1', '2', '3', '4'],
          onChanged: (String newValue) {
            setState(() {
              dropdownValue2 = newValue;
            });
          }),
    ]);
  }

Instead creating a function which creates the widget tree, consider creating your own widget for the DropdownButton.与其创建一个创建小部件树的函数,不如考虑为 DropdownButton 创建您自己的小部件。 This should yield a performance benefit in most cases, see this answer for an explantion why this is the case.在大多数情况下,这应该会产生性能优势,请参阅此答案以了解为什么会这样。

You could create your widget like this:你可以像这样创建你的小部件:

class MyDropdownButton extends StatelessWidget {
  const MyDropdownButton({
    Key key,
    @required this.value,
    @required this.labels,
    @required this.onChanged,
  }) : super(key: key);

  final String value;
  final List<String> labels;
  final ValueChanged<String> onChanged;

  @override
  Widget build(BuildContext context) {
    return DropdownButton<String>(
      value: value,
      icon: Icon(Icons.arrow_downward),
      iconSize: 24,
      elevation: 16,
      style: TextStyle(
        color: Colors.deepPurple
      ),
      underline: Container(
        height: 2,
        color: Colors.deepPurpleAccent,
      ),
      onChanged: onChanged,
      items: Cost [
        for (final label in labels)
           DropdownMenuItem<String>(
             key: ValueKey(label),
             value: value,
             child: Text(value),
           )
      ],
    );
  }
}

Then you can use it like this:然后你可以像这样使用它:

return MyDropdownButton(
  value: dropdownValue,
  labels: ["one", "two", "three"],
  onChanged: (label) {
    setState(() {
       dropdownValue = label;
    });
  },
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM