Update MaterialStatesController docs for calling setState in a listener (#143453)

fixes [Calling `setState` in a `MaterialStatesController` listener and `MaterialStateController.update` causes Exception](https://github.com/flutter/flutter/issues/138986)

### Description
`MaterialStatesController` listener  calls `setState` during build when `MaterialStatesController.update` listener calls `notifyListeners`.

I tried fixing this issue by putting `notifyListeners` in a post-frame callback. However, this breaks existing customer tests (particularly super editor tests).

A safer approach would be to document that the listener's `setState` call should be in a post-frame callback to delay it and not call this during the build phase triggered by the `MaterialStatesController.update` in the widgets such as InkWell or buttons.
This commit is contained in:
Taha Tesser 2024-02-16 09:43:50 +02:00 committed by GitHub
parent 8129797045
commit a603a17875
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -760,6 +760,14 @@ class MaterialStatePropertyAll<T> implements MaterialStateProperty<T> {
/// [MaterialState.focused] to its controller. When the widget gains the
/// or loses the focus it will [update] its controller's [value] and
/// notify listeners of the change.
///
/// When calling `setState` in a [MaterialStatesController] listener, use the
/// [SchedulerBinding.addPostFrameCallback] to delay the call to `setState` after
/// the frame has been rendered. It's generally prudent to use the
/// [SchedulerBinding.addPostFrameCallback] because some of the widgets that
/// depend on [MaterialStatesController] may call [update] in their build method.
/// In such cases, listener's that call `setState` - during the build phase - will cause
/// an error.
class MaterialStatesController extends ValueNotifier<Set<MaterialState>> {
/// Creates a MaterialStatesController.
MaterialStatesController([Set<MaterialState>? value]) : super(<MaterialState>{...?value});