diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart index 2b697db9cf..b59e1c5aa3 100644 --- a/packages/flutter/lib/src/widgets/framework.dart +++ b/packages/flutter/lib/src/widgets/framework.dart @@ -4586,13 +4586,7 @@ class StatefulElement extends ComponentElement { } @override - Widget build() { - if (_didChangeDependencies) { - _state.didChangeDependencies(); - _didChangeDependencies = false; - } - return state.build(this); - } + Widget build() => _state.build(this); /// The [State] instance associated with this location in the tree. /// @@ -4642,6 +4636,15 @@ class StatefulElement extends ComponentElement { super._firstBuild(); } + @override + void performRebuild() { + if (_didChangeDependencies) { + _state.didChangeDependencies(); + _didChangeDependencies = false; + } + super.performRebuild(); + } + @override void update(StatefulWidget newWidget) { super.update(newWidget); diff --git a/packages/flutter/test/widgets/framework_test.dart b/packages/flutter/test/widgets/framework_test.dart index 1a5fba15c8..b2f3bb206b 100644 --- a/packages/flutter/test/widgets/framework_test.dart +++ b/packages/flutter/test/widgets/framework_test.dart @@ -1259,6 +1259,80 @@ void main() { expect(state.didChangeDependenciesCount, 3); expect(state.deactivatedCount, 2); }); + + testWidgets('StatefulElement subclass can decorate State.build', (WidgetTester tester) async { + bool isDidChangeDependenciesDecorated; + bool isBuildDecorated; + + final Widget child = Decorate( + didChangeDependencies: (bool value) { + isDidChangeDependenciesDecorated = value; + }, + build: (bool value) { + isBuildDecorated = value; + } + ); + + await tester.pumpWidget(Inherited(0, child: child)); + + expect(isBuildDecorated, isTrue); + expect(isDidChangeDependenciesDecorated, isFalse); + + await tester.pumpWidget(Inherited(1, child: child)); + + expect(isBuildDecorated, isTrue); + expect(isDidChangeDependenciesDecorated, isFalse); + }); +} + +class Decorate extends StatefulWidget { + const Decorate({ + Key key, + @required this.didChangeDependencies, + @required this.build + }) : + assert(didChangeDependencies != null), + assert(build != null), + super(key: key); + + final void Function(bool isInBuild) didChangeDependencies; + final void Function(bool isInBuild) build; + + @override + _DecorateState createState() => _DecorateState(); + + @override + DecorateElement createElement() => DecorateElement(this); +} + +class DecorateElement extends StatefulElement { + DecorateElement(Decorate widget): super(widget); + + bool isDecorated = false; + + @override + Widget build() { + try { + isDecorated = true; + return super.build(); + } finally { + isDecorated = false; + } + } +} + +class _DecorateState extends State { + @override + void didChangeDependencies() { + super.didChangeDependencies(); + widget.didChangeDependencies.call((context as DecorateElement).isDecorated); + } + @override + Widget build(covariant DecorateElement context) { + context.dependOnInheritedWidgetOfExactType(); + widget.build.call(context.isDecorated); + return Container(); + } } class NullChildTest extends Widget {