处理儿童水龙头

时间:2018-04-25 00:15:28

标签: flutter

我是Flutter的初学者,我正在尝试创建一个名为IconSelect的自定义Widget。它应该呈现带有图例的图标列表,用户将只选择一个选项。当用户点击图标时,它应该更改所选图标的背景颜色并取消选择所有其他图标。

我的第一个方法是将IconSelect类创建为Stateful小部件,将另一个名为IconSelectItem的小部件创建为Stateless。 IconSelect将有一个子属性,包含IconSelectItem的实例。

如何处理儿童水龙头以更改IconSelect状态?其他人的任何想法都是适用的吗?

我的代码:

class IconSelect extends StatefulWidget {
  final List<IconSelectItem> children;
  final ValueChanged<int> onSaved;

  IconSelect({
    this.children,
    this.onSaved
  });

  @override
  State<StatefulWidget> createState() => new IconSelectState();
}

class IconSelectState extends State<IconSelect> {
  int _selectedValue;

  _handleTap(int value) {
    setState(() {
      _selectedValue = value;
    });

    widget.onSaved(_selectedValue);
  }

  @override
  Widget build(BuildContext context) {
    return new Row(
      children: widget.children,
    );
  }

  @override
  void initState() {
    super.initState();

    // I tried the code below without success
    widget.children.forEach((IconSelectItem item) {
      item.onTap = _handleTap(item);
    });
  }
}

class IconSelectItem extends StatelessWidget {
  final Icon icon;
  final String legend;
  final int value;
  VoidCallback onTap;
  final bool _selected = false;

  IconSelectItem({
    Key key,
    this.icon,
    this.legend,
    this.value,
  }) : super(key: key);

  _handleTap() {
    onTap();
  }

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: () => _handleTap(),
      child: new Column(
        children: <Widget>[
          new CircleAvatar(
            radius: 30.0,
            child: icon,
            backgroundColor: _selected ? Colors.blue : Colors.white,
          ),
          new Center(
            child: new Text(legend),
          )
        ],
      ),
    );
  }
}

1 个答案:

答案 0 :(得分:0)

在IconSelectItem的祖先上调用setState

class YourPageState extends State<YourPage> {
  int _selectedValue;

  @override
  Widget build(BuildContext context) {
    return new Row(
      children: widget.items.map((Item item) {
        return new GestureDetector(
          onTap: () {
            // this class is a ancestor of IconSelectItem.
            // setState will rebuild children.
            setState(() {
              _selectedValue = value;
            });
          },
          child: new IconSelectItem(
            icon: item.icon,
            legend: item.legend,
            value: item.value,
            // every time _selectedValue changes,
            // IconSelectItem is rebuild by setState.
            selected: item.value == _selectedValue,
          ),
        );
      }).toList(),
    );
  }
}

class IconSelectItem extends StatelessWidget {
  final Icon icon;
  final String legend;
  final int value;
  final bool selected;

  IconSelectItem({
    Key key,
    this.icon,
    this.legend,
    this.value,
    this.selected = false,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new CircleAvatar(
          radius: 30.0,
          child: icon,
          backgroundColor: selected ? Colors.blue : Colors.white,
        ),
        new Center(
          child: new Text(legend),
        ),
      ],
    );
  }
}