Изменение состояния виджета Flutter извне его Класс состояния

Я создал DropdownButton как StatefulWidget. Класс называется MyDropDown, с соответствующим состоянием MyDropDownState.

Я создал функцию сброса в классе MyDropDownState:

void reset(){
    setState((){
        _selection = null;
    });
}

который установит нулевое значение и задает состояние выпадающего меню, эффективно сбросив выпадающее меню.

Ядром этой проблемы является вызов этой функции при нажатии IconButton на AppBar. Я пробовал несколько способов и просто не могу получить доступ к состоянию созданного мной класса MyDropDown.

Это код MyDropDown и его состояние, упрощенное:

class MyDropDown extends StatefulWidget {

  final Map<String, String> _itemMap;

  MyDropDown(this._itemMap);

  @override
  MyDropDownState createState() => new MyDropDownState();
}

class MyDropDownState extends State<MyDropDown> {

  String _selection;

  void reset(){
    setState((){
      _selection = null;
    });
  }

  @override
  void initState() {
    _selection = null;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
      return new DropdownButton(
          value: _selection,
          //getDropItems builds dropdown items
          items: getDropItems(widget._itemMap),
          onChanged: (s) {
            setState(() {
              _selection = s;
            });
          },
      );
  }

}

На моей главной странице я создаю новый MyDropDown

final MyDropDown cityDropdown = new MyDropDown(cityLookup);

то это AppBar (внутри Scaffold), который содержит IconButton, который я хочу нажать, чтобы сбросить Dropdown.

appBar : new AppBar(
    title: new Text('Filter Jobs'),
    actions: <Widget>[
      new IconButton(
          icon: new Icon(Icons.refresh),
          onPressed: () {
            print('Reset dropdowns');
            //this is where I would call reset() on cityDropdown state, if I could figure out how to get to it :/
          },
      ),
    ],
  ),

Ответы

Ответ 1

Самое простое решение здесь - использовать GlobalKey<T>: https://docs.flutter.io/flutter/widgets/GlobalKey-class.html

  1. Создайте GlobalKey<MyDropDownState> в GlobalKey<MyDropDownState> вашей страницы и передайте его в MyDropDown.
  2. Используйте этот ключ в своем key.currentState.reset(): key.currentState.reset();

Кроме того, вы можете использовать шаблон контроллера, который использует сам Флаттер. Например, TextField имеет TextEditingController: https://docs.flutter.io/flutter/widgets/TextEditingController-class.html

Ответ 2

Можете ли вы опубликовать код после того, как исправили его? Пожалуйста? У меня проблемы с решением аналогичной проблемы