На вашем DropdownButton
есть обратный вызов onChanged
:
onChanged: (String value) {
_chosenValue = value;
(widget._key == 'Favourite Animal' && _chosenValue == 'Cat') ? cat = true : cat = false;
setState(() {
});
}
Этот вызов setState()
будет сделан для виджета Dropdown, а не для более высокого виджета Filter.
Одним из способов решения этой проблемы является добавление в ваш пользовательский класс Dropdown обратного вызова функции:
class Dropdown extends StatefulWidget {
final String _key;
final List<String> _values;
final Function callback;
Dropdown(this._key, this._values, this.callback);
@override
_DropdownState createState() => _DropdownState();
}
И в свойстве onChanged:
onChanged: (String value) {
_chosenValue = value;
(widget._key == 'Favourite Animal' && _chosenValue == 'Cat') ? cat = true : cat = false;
callback();
},
Это вызовет обратный вызов Вы определяете при создании Dropdown:
children: <Widget>[
Dropdown('Gender', ['Female', 'Male'], callbackFunc),
Dropdown('Age', ['<15', '15-20', '>20'], callbackFunc),
Dropdown('Favourite Animal', ['Cat', 'Dog', 'Hamster'], callbackFunc),
(cat) ? Dropdown('Favourite cat-toy', ['Toy-mouse', 'Ribbon', 'Ball'], callbackFunc) : Text('')
],
Где callbackFun c может быть таким простым:
void callbackFunc(){
setState((){});
}
Конечно, это не самое элегантное решение. Поскольку вы используете обратный вызов, вы можете отменить все глобальные переменные, которые вы использовали, и просто использовать обратный вызов с аргументом:
void callbackFunc(String value){
if (value=='cat')
choseCat=true;
else
choseCat=false;
setState((){});
}
Кроме того, вам не нужно проверять ключ виджета для проверки какой выпадающий называется. Вы можете проверить, является ли обратный вызов нулевым, прежде чем вызывать его, и назначить функцию обратного вызова только соответствующим:
children: <Widget>[
Dropdown('Gender', ['Female', 'Male']),
Dropdown('Age', ['<15', '15-20', '>20']),
Dropdown('Favourite Animal', ['Cat', 'Dog', 'Hamster'], callbackFunc),
(cat) ? Dropdown('Favourite cat-toy', ['Toy-mouse', 'Ribbon', 'Ball']) : Text('')
],
[...]
onChanged: (String value) {
_chosenValue = value;
(widget._key == 'Favourite Animal' && _chosenValue == 'Cat') ? cat = true : cat = false;
if (callback)
callback();
},
Не забудьте сделать этот обратный вызов необязательным в этом случае:
Dropdown({@required this._key, @required this._values, this.callback});
Я уверен, что многие другие оптимизации могут быть сделаны с этим подходом. А с большими приложениями следует выбирать другие подходы к управлению состоянием , чтобы сделать вашу жизнь проще.