-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Closed
Labels
a: error messageError messages from the Flutter frameworkError messages from the Flutter frameworkf: material designflutter/packages/flutter/material repository.flutter/packages/flutter/material repository.found in release: 3.16Found to occur in 3.16Found to occur in 3.16found in release: 3.19Found to occur in 3.19Found to occur in 3.19frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-designOwned by Design Languages teamOwned by Design Languages team
Description
On the MenuItemButton widget, if widget.focusNode is updated to null, didUpdateWidget would throw.
Steps to reproduce
Change menu item focus node to null
Expected outcome
Doesn't throw
Actual outcome
Throws
Code sample
import 'package:flutter/material.dart';
/// Flutter code sample for [MenuAnchor].
void main() => runApp(const MenuApp());
class MenuApp extends StatelessWidget {
const MenuApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(useMaterial3: true),
home: const Scaffold(body: SafeArea(child: MyCascadingMenu())),
);
}
}
class MyCascadingMenu extends StatefulWidget {
const MyCascadingMenu({super.key});
@override
State<MyCascadingMenu> createState() => _MyCascadingMenuState();
}
class _MyCascadingMenuState extends State<MyCascadingMenu> {
late FocusNode? _buttonFocusNode = FocusNode();
@override
Widget build(BuildContext context) {
return MenuAnchor(
menuChildren: <Widget>[
MenuItemButton(
focusNode: _buttonFocusNode,
closeOnActivate: false,
child: 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'),
);
},
);
}
}Here is a gist demonstrating the bug in action on the Master branch: https://dartpad.dev/?id=a7da3f81557b11f7080b1f5a8afa0779&channel=master
Here is the code in the master material library: https://github.com/flutter/flutter/blob/b5262f0d80eb6da1b1cd6ceff0943367fbc29331/packages/flutter/lib/src/material/menu_anchor.dart#L1078C8-L1078C53
The code throws on both master and stable branches.
Relevate framework code
class _MenuItemButtonState extends State<MenuItemButton> {
FocusNode? _internalFocusNode;
FocusNode get _focusNode => widget.focusNode ?? _internalFocusNode!;
// ...
@override
void didUpdateWidget(MenuItemButton oldWidget) {
if (widget.focusNode != oldWidget.focusNode) {
// **BUG?** If widget.focusNode changes to null, this appears to throw
_focusNode.removeListener(_handleFocusChange);
if (widget.focusNode != null) {
_internalFocusNode?.dispose();
_internalFocusNode = null;
}
_createInternalFocusNodeIfNeeded();
_focusNode.addListener(_handleFocusChange);
}
super.didUpdateWidget(oldWidget);
}
// ...
void _createInternalFocusNodeIfNeeded() {
if (widget.focusNode == null) {
_internalFocusNode = FocusNode();
assert(() {
if (_internalFocusNode != null) {
_internalFocusNode!.debugLabel = '$MenuItemButton(${widget.child})';
}
return true;
}());
}
}
}Metadata
Metadata
Assignees
Labels
a: error messageError messages from the Flutter frameworkError messages from the Flutter frameworkf: material designflutter/packages/flutter/material repository.flutter/packages/flutter/material repository.found in release: 3.16Found to occur in 3.16Found to occur in 3.16found in release: 3.19Found to occur in 3.19Found to occur in 3.19frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-designOwned by Design Languages teamOwned by Design Languages team