Fix custom Elements that wants to decorate State.build (#49925)
This commit is contained in:
parent
9e9e741672
commit
a1143d174f
@ -4586,13 +4586,7 @@ class StatefulElement extends ComponentElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build() {
|
Widget build() => _state.build(this);
|
||||||
if (_didChangeDependencies) {
|
|
||||||
_state.didChangeDependencies();
|
|
||||||
_didChangeDependencies = false;
|
|
||||||
}
|
|
||||||
return state.build(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The [State] instance associated with this location in the tree.
|
/// The [State] instance associated with this location in the tree.
|
||||||
///
|
///
|
||||||
@ -4642,6 +4636,15 @@ class StatefulElement extends ComponentElement {
|
|||||||
super._firstBuild();
|
super._firstBuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void performRebuild() {
|
||||||
|
if (_didChangeDependencies) {
|
||||||
|
_state.didChangeDependencies();
|
||||||
|
_didChangeDependencies = false;
|
||||||
|
}
|
||||||
|
super.performRebuild();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void update(StatefulWidget newWidget) {
|
void update(StatefulWidget newWidget) {
|
||||||
super.update(newWidget);
|
super.update(newWidget);
|
||||||
|
@ -1259,6 +1259,80 @@ void main() {
|
|||||||
expect(state.didChangeDependenciesCount, 3);
|
expect(state.didChangeDependenciesCount, 3);
|
||||||
expect(state.deactivatedCount, 2);
|
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<Decorate> {
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
widget.didChangeDependencies.call((context as DecorateElement).isDecorated);
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Widget build(covariant DecorateElement context) {
|
||||||
|
context.dependOnInheritedWidgetOfExactType<Inherited>();
|
||||||
|
widget.build.call(context.isDecorated);
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NullChildTest extends Widget {
|
class NullChildTest extends Widget {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user