diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart index 23d22f504db..a9cb134de20 100644 --- a/packages/flutter/lib/src/material/scaffold.dart +++ b/packages/flutter/lib/src/material/scaffold.dart @@ -1960,17 +1960,21 @@ class ScaffoldState extends State with TickerProviderStateMixin, Resto bool get isEndDrawerOpen => _endDrawerOpened.value; void _drawerOpenedCallback(bool isOpened) { - setState(() { - _drawerOpened.value = isOpened; - }); - widget.onDrawerChanged?.call(isOpened); + if (_drawerOpened.value != isOpened) { + setState(() { + _drawerOpened.value = isOpened; + }); + widget.onDrawerChanged?.call(isOpened); + } } void _endDrawerOpenedCallback(bool isOpened) { - setState(() { - _endDrawerOpened.value = isOpened; - }); - widget.onEndDrawerChanged?.call(isOpened); + if (_endDrawerOpened.value != isOpened) { + setState(() { + _endDrawerOpened.value = isOpened; + }); + widget.onEndDrawerChanged?.call(isOpened); + } } /// Opens the [Drawer] (if any). diff --git a/packages/flutter/test/material/scaffold_test.dart b/packages/flutter/test/material/scaffold_test.dart index d1d372a51f3..3deefd8328f 100644 --- a/packages/flutter/test/material/scaffold_test.dart +++ b/packages/flutter/test/material/scaffold_test.dart @@ -50,6 +50,40 @@ void main() { expect(false, isEndDrawerOpen); }); + testWidgets('Scaffold drawer callback test - only call when changed', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/87914 + bool onDrawerChangedCalled = false; + bool onEndDrawerChangedCalled = false; + + await tester.pumpWidget(MaterialApp( + home: Scaffold( + drawer: Container( + color: Colors.blue, + ), + onDrawerChanged: (bool isOpen) { + onDrawerChangedCalled = true; + }, + endDrawer: Container( + color: Colors.green, + ), + onEndDrawerChanged: (bool isOpen) { + onEndDrawerChangedCalled = true; + }, + body: Container(), + ), + )); + + await tester.flingFrom(Offset.zero, const Offset(10.0, 0.0), 10.0); + expect(false, onDrawerChangedCalled); + + await tester.pumpAndSettle(); + + final double width = tester.getSize(find.byType(MaterialApp)).width; + await tester.flingFrom(Offset(width - 1, 0.0), const Offset(-10.0, 0.0), 10.0); + await tester.pumpAndSettle(); + expect(false, onEndDrawerChangedCalled); + }); + testWidgets('Scaffold control test', (WidgetTester tester) async { final Key bodyKey = UniqueKey(); Widget boilerplate(Widget child) {