Unverified Commit da3b2a2f authored by Markus Aksli's avatar Markus Aksli Committed by GitHub

Fix `Scaffold` `setState` during locked framework due to open drawer (#107173)

parent 2f0a2525
...@@ -2029,7 +2029,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto ...@@ -2029,7 +2029,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
bool get isEndDrawerOpen => _endDrawerOpened.value; bool get isEndDrawerOpen => _endDrawerOpened.value;
void _drawerOpenedCallback(bool isOpened) { void _drawerOpenedCallback(bool isOpened) {
if (_drawerOpened.value != isOpened) { if (_drawerOpened.value != isOpened && _drawerKey.currentState != null) {
setState(() { setState(() {
_drawerOpened.value = isOpened; _drawerOpened.value = isOpened;
}); });
...@@ -2038,7 +2038,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto ...@@ -2038,7 +2038,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
} }
void _endDrawerOpenedCallback(bool isOpened) { void _endDrawerOpenedCallback(bool isOpened) {
if (_endDrawerOpened.value != isOpened) { if (_endDrawerOpened.value != isOpened && _endDrawerKey.currentState != null) {
setState(() { setState(() {
_endDrawerOpened.value = isOpened; _endDrawerOpened.value = isOpened;
}); });
......
...@@ -422,6 +422,87 @@ void main() { ...@@ -422,6 +422,87 @@ void main() {
expect(find.text('Drawer'), findsNothing); expect(find.text('Drawer'), findsNothing);
}); });
testWidgets('Disposing drawer does not crash if drawer is open and framework is locked', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/34978
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
tester.binding.window.physicalSizeTestValue = const Size(1800.0, 2400.0);
await tester.pumpWidget(
MaterialApp(
home: OrientationBuilder(
builder: (BuildContext context, Orientation orientation) {
switch (orientation) {
case Orientation.portrait:
return Scaffold(
drawer: const Text('drawer'),
body: Container(),
);
case Orientation.landscape:
return Scaffold(
appBar: AppBar(),
body: Container(),
);
}
},
),
),
);
expect(find.text('drawer'), findsNothing);
// Using a global key is a workaround for this issue.
final ScaffoldState portraitScaffoldState = tester.firstState(find.byType(Scaffold));
portraitScaffoldState.openDrawer();
await tester.pumpAndSettle();
expect(find.text('drawer'), findsOneWidget);
// Change the orientation and cause the drawer controller to be disposed
// while the framework is locked.
tester.binding.window.physicalSizeTestValue = const Size(2400.0, 1800.0);
await tester.pumpAndSettle();
expect(find.byType(BackButton), findsNothing);
});
testWidgets('Disposing endDrawer does not crash if endDrawer is open and framework is locked', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/34978
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
tester.binding.window.physicalSizeTestValue = const Size(1800.0, 2400.0);
await tester.pumpWidget(
MaterialApp(
home: OrientationBuilder(
builder: (BuildContext context, Orientation orientation) {
switch (orientation) {
case Orientation.portrait:
return Scaffold(
endDrawer: const Text('endDrawer'),
body: Container(),
);
case Orientation.landscape:
return Scaffold(
appBar: AppBar(),
body: Container(),
);
}
},
),
),
);
expect(find.text('endDrawer'), findsNothing);
// Using a global key is a workaround for this issue.
final ScaffoldState portraitScaffoldState = tester.firstState(find.byType(Scaffold));
portraitScaffoldState.openEndDrawer();
await tester.pumpAndSettle();
expect(find.text('endDrawer'), findsOneWidget);
// Change the orientation and cause the drawer controller to be disposed
// while the framework is locked.
tester.binding.window.physicalSizeTestValue = const Size(2400.0, 1800.0);
await tester.pumpAndSettle();
expect(find.byType(BackButton), findsNothing);
});
testWidgets('ScaffoldState close end drawer', (WidgetTester tester) async { testWidgets('ScaffoldState close end drawer', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment