From 4a6cbefe34933982792165e16aa8a58e7c2cf9d7 Mon Sep 17 00:00:00 2001 From: Jude Selase Kwashie <64037520+SelaseKay@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:21:50 +0000 Subject: [PATCH] Fix null operator error when tapping on 'MenuItemButton' (#142230) This PR fixes null operator error when you change focus node of a 'MenuItemButton' to null. fixes: [issue142095](https://github.com/flutter/flutter/issues/142095) --- .../flutter/lib/src/material/menu_anchor.dart | 2 +- .../test/material/menu_anchor_test.dart | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/material/menu_anchor.dart b/packages/flutter/lib/src/material/menu_anchor.dart index 451da7ca109..a496dd88513 100644 --- a/packages/flutter/lib/src/material/menu_anchor.dart +++ b/packages/flutter/lib/src/material/menu_anchor.dart @@ -1071,7 +1071,7 @@ class _MenuItemButtonState extends State { @override void didUpdateWidget(MenuItemButton oldWidget) { if (widget.focusNode != oldWidget.focusNode) { - _focusNode.removeListener(_handleFocusChange); + (oldWidget.focusNode ?? _internalFocusNode)?.removeListener(_handleFocusChange); if (widget.focusNode != null) { _internalFocusNode?.dispose(); _internalFocusNode = null; diff --git a/packages/flutter/test/material/menu_anchor_test.dart b/packages/flutter/test/material/menu_anchor_test.dart index a9fce196a62..a18aacd8042 100644 --- a/packages/flutter/test/material/menu_anchor_test.dart +++ b/packages/flutter/test/material/menu_anchor_test.dart @@ -2599,6 +2599,57 @@ void main() { ); }); + testWidgets('tapping MenuItemButton with null focus node', (WidgetTester tester) async { + + FocusNode? buttonFocusNode = FocusNode(); + + // Build our app and trigger a frame. + await tester.pumpWidget( + MaterialApp( + home: StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return MenuAnchor( + menuChildren: [ + MenuItemButton( + focusNode: buttonFocusNode, + closeOnActivate: false, + child: const Text('Set focus to null'), + onPressed: () { + setState((){ + buttonFocusNode = null; + }); + }, + ), + ], + builder: (BuildContext context, MenuController controller, Widget? child) { + return TextButton( + onPressed: () { + if (controller.isOpen) { + controller.close(); + } else { + controller.open(); + } + }, + child: const Text('OPEN MENU'), + ); + }, + ); + } + ), + ), + ); + + await tester.tap(find.text('OPEN MENU')); + await tester.pump(); + + expect(find.text('Set focus to null'), findsOneWidget); + + await tester.tap(find.text('Set focus to null')); + await tester.pumpAndSettle(); + + expect(tester.takeException(), isNull); + }); + testWidgets('constrained menus show up in the right place in RTL', (WidgetTester tester) async { await changeSurfaceSize(tester, const Size(300, 300)); await tester.pumpWidget(