Fix DropdownMenu can be focused and updated when disabled (#149737)
## Description This PRs fixes `DropdownMenu` behaviors when disabled. Before this PR the `DropdownMenu` value can be changed when `DropdownMenu.enabled` was false because the inner `IconButton` was not disabled so it can get focus (for instance using tab key). After this PR, the inner `TextField` and the inner `IconButton` are disabled when `DropdownMenu.enabled` is false. ## Related Issue Fixes https://github.com/flutter/flutter/issues/149598. ## Tests Updates 1 test. Adds 1 test.
This commit is contained in:
parent
ad462e2783
commit
fdb74fd3e7
@ -655,7 +655,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
||||
style: effectiveStyle,
|
||||
leadingIcon: entry.leadingIcon,
|
||||
trailingIcon: entry.trailingIcon,
|
||||
onPressed: entry.enabled
|
||||
onPressed: entry.enabled && widget.enabled
|
||||
? () {
|
||||
_localTextEditingController?.value = TextEditingValue(
|
||||
text: entry.label,
|
||||
@ -676,7 +676,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
||||
|
||||
void handleUpKeyInvoke(_) {
|
||||
setState(() {
|
||||
if (!_menuHasEnabledItem || !_controller.isOpen) {
|
||||
if (!widget.enabled || !_menuHasEnabledItem || !_controller.isOpen) {
|
||||
return;
|
||||
}
|
||||
_enableFilter = false;
|
||||
@ -695,7 +695,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
||||
|
||||
void handleDownKeyInvoke(_) {
|
||||
setState(() {
|
||||
if (!_menuHasEnabledItem || !_controller.isOpen) {
|
||||
if (!widget.enabled || !_menuHasEnabledItem || !_controller.isOpen) {
|
||||
return;
|
||||
}
|
||||
_enableFilter = false;
|
||||
@ -786,7 +786,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
||||
isSelected: controller.isOpen,
|
||||
icon: widget.trailingIcon ?? const Icon(Icons.arrow_drop_down),
|
||||
selectedIcon: widget.selectedTrailingIcon ?? const Icon(Icons.arrow_drop_up),
|
||||
onPressed: () {
|
||||
onPressed: !widget.enabled ? null : () {
|
||||
handlePressed(controller);
|
||||
},
|
||||
),
|
||||
@ -799,6 +799,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
||||
|
||||
final Widget textField = TextField(
|
||||
key: _anchorKey,
|
||||
enabled: widget.enabled,
|
||||
mouseCursor: effectiveMouseCursor,
|
||||
focusNode: widget.focusNode,
|
||||
canRequestFocus: canRequestFocus(),
|
||||
@ -825,7 +826,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
||||
}
|
||||
controller.close();
|
||||
},
|
||||
onTap: () {
|
||||
onTap: !widget.enabled ? null : () {
|
||||
handlePressed(controller);
|
||||
},
|
||||
onChanged: (String text) {
|
||||
@ -837,7 +838,6 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
||||
},
|
||||
inputFormatters: widget.inputFormatters,
|
||||
decoration: InputDecoration(
|
||||
enabled: widget.enabled,
|
||||
label: widget.label,
|
||||
hintText: widget.hintText,
|
||||
helperText: widget.helperText,
|
||||
|
@ -83,11 +83,9 @@ void main() {
|
||||
expect(material.textStyle?.height, 1.43);
|
||||
});
|
||||
|
||||
testWidgets('DropdownMenu can be disabled', (WidgetTester tester) async {
|
||||
final ThemeData themeData = ThemeData();
|
||||
testWidgets('Inner TextField is disabled when DropdownMenu is disabled', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: themeData,
|
||||
home: Scaffold(
|
||||
body: SafeArea(
|
||||
child: DropdownMenu<TestMenu>(
|
||||
@ -100,7 +98,7 @@ void main() {
|
||||
);
|
||||
|
||||
final TextField textField = tester.widget(find.byType(TextField));
|
||||
expect(textField.decoration?.enabled, false);
|
||||
expect(textField.enabled, false);
|
||||
final Finder menuMaterial = find.ancestor(
|
||||
of: find.byType(SingleChildScrollView),
|
||||
matching: find.byType(Material),
|
||||
@ -116,6 +114,25 @@ void main() {
|
||||
expect(updatedMenuMaterial, findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('Inner IconButton is disabled when DropdownMenu is disabled', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/149598.
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SafeArea(
|
||||
child: DropdownMenu<TestMenu>(
|
||||
enabled: false,
|
||||
dropdownMenuEntries: menuChildren,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final IconButton trailingButton = tester.widget(find.widgetWithIcon(IconButton, Icons.arrow_drop_down).first);
|
||||
expect(trailingButton.onPressed, null);
|
||||
});
|
||||
|
||||
testWidgets('Material2 - The width of the text field should always be the same as the menu view',
|
||||
(WidgetTester tester) async {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user