Обработка детских кранов - PullRequest
0 голосов
/ 25 апреля 2018

Я новичок во Flutter и пытаюсь создать собственный виджет под названием IconSelect. Следует отобразить список значков с легендой, и пользователь выберет только один вариант. Когда пользователь касается значка, он должен изменить цвет фона выбранного значка и отменить выбор всех остальных.

Моим первым подходом было создание класса IconSelect в качестве виджета с сохранением состояния, а другого виджета с именем IconSelectItem в качестве состояния без состояния. И 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 голосов
/ 27 апреля 2018

вызов setState для предка IconSelectItem:

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),
        ),
      ],
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...