Added enableFeedback property PopupMenuButton (#69890)

This commit is contained in:
Chinmoy 2020-11-19 23:43:05 +05:30 committed by GitHub
parent 7b40272e10
commit d2f06f6f05
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 104 additions and 1 deletions

View file

@ -945,6 +945,7 @@ class PopupMenuButton<T> extends StatefulWidget {
this.enabled = true,
this.shape,
this.color,
this.enableFeedback,
}) : assert(itemBuilder != null),
assert(offset != null),
assert(enabled != null),
@ -1029,6 +1030,16 @@ class PopupMenuButton<T> extends StatefulWidget {
/// Theme.of(context).cardColor is used.
final Color? color;
/// Whether detected gestures should provide acoustic and/or haptic feedback.
///
/// For example, on Android a tap will produce a clicking sound and a
/// long-press will produce a short vibration, when feedback is enabled.
///
/// See also:
///
/// * [Feedback] for providing platform-specific feedback to certain actions.
final bool? enableFeedback;
@override
PopupMenuButtonState<T> createState() => PopupMenuButtonState<T>();
}
@ -1109,6 +1120,10 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
@override
Widget build(BuildContext context) {
final bool enableFeedback = widget.enableFeedback
?? PopupMenuTheme.of(context).enableFeedback
?? true;
assert(debugCheckHasMaterialLocalizations(context));
if (widget.child != null)
@ -1118,6 +1133,7 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
onTap: widget.enabled ? showButtonMenu : null,
canRequestFocus: _canRequestFocus,
child: widget.child,
enableFeedback: enableFeedback,
),
);
@ -1126,6 +1142,7 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
padding: widget.padding,
tooltip: widget.tooltip ?? MaterialLocalizations.of(context).showMenuTooltip,
onPressed: widget.enabled ? showButtonMenu : null,
enableFeedback: enableFeedback,
);
}
}

View file

@ -37,6 +37,7 @@ class PopupMenuThemeData with Diagnosticable {
this.shape,
this.elevation,
this.textStyle,
this.enableFeedback,
});
/// The background color of the popup menu.
@ -51,6 +52,11 @@ class PopupMenuThemeData with Diagnosticable {
/// The text style of items in the popup menu.
final TextStyle? textStyle;
/// If specified, defines the feedback property for [PopupMenuButton].
///
/// If [PopupMenuButton.enableFeedback] is provided, [enableFeedback] is ignored.
final bool? enableFeedback;
/// Creates a copy of this object with the given fields replaced with the
/// new values.
PopupMenuThemeData copyWith({
@ -58,12 +64,14 @@ class PopupMenuThemeData with Diagnosticable {
ShapeBorder? shape,
double? elevation,
TextStyle? textStyle,
bool? enableFeedback,
}) {
return PopupMenuThemeData(
color: color ?? this.color,
shape: shape ?? this.shape,
elevation: elevation ?? this.elevation,
textStyle: textStyle ?? this.textStyle,
enableFeedback: enableFeedback ?? this.enableFeedback,
);
}
@ -81,6 +89,7 @@ class PopupMenuThemeData with Diagnosticable {
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
elevation: lerpDouble(a?.elevation, b?.elevation, t),
textStyle: TextStyle.lerp(a?.textStyle, b?.textStyle, t),
enableFeedback: t < 0.5 ? a?.enableFeedback : b?.enableFeedback,
);
}
@ -91,6 +100,7 @@ class PopupMenuThemeData with Diagnosticable {
shape,
elevation,
textStyle,
enableFeedback,
);
}
@ -104,7 +114,8 @@ class PopupMenuThemeData with Diagnosticable {
&& other.elevation == elevation
&& other.color == color
&& other.shape == shape
&& other.textStyle == textStyle;
&& other.textStyle == textStyle
&& other.enableFeedback == enableFeedback;
}
@override
@ -114,6 +125,7 @@ class PopupMenuThemeData with Diagnosticable {
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
properties.add(DoubleProperty('elevation', elevation, defaultValue: null));
properties.add(DiagnosticsProperty<TextStyle>('text style', textStyle, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('enableFeedback', enableFeedback, defaultValue: null));
}
}

View file

@ -10,6 +10,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/material.dart';
import '../widgets/semantics_tester.dart';
import 'feedback_tester.dart';
void main() {
testWidgets('Navigator.push works within a PopupMenuButton', (WidgetTester tester) async {
@ -1799,6 +1800,79 @@ void main() {
lessThan(600 - windowPaddingBottom), // Device height is 600.
);
});
group('feedback', () {
late FeedbackTester feedback;
setUp(() {
feedback = FeedbackTester();
});
tearDown(() {
feedback.dispose();
});
Widget buildFrame({ bool? widgetEnableFeedack, bool? themeEnableFeedback }) {
return MaterialApp(
home: Scaffold(
body: PopupMenuTheme(
data: PopupMenuThemeData(
enableFeedback: themeEnableFeedback,
),
child: PopupMenuButton<int>(
enableFeedback: widgetEnableFeedack,
child: const Text('Show Menu'),
itemBuilder: (BuildContext context) {
return <PopupMenuItem<int>>[
const PopupMenuItem<int>(
value: 1,
child: Text('One'),
),
];
},
),
),
),
);
}
testWidgets('PopupMenuButton enableFeedback works properly', (WidgetTester tester) async {
//PopupMenuButton with enabled feedback
await tester.pumpWidget(buildFrame(widgetEnableFeedack: true));
await tester.tap(find.text('Show Menu'));
await tester.pumpAndSettle();
expect(feedback.clickSoundCount, 1);
expect(feedback.hapticCount, 0);
//PopupMenuButton with disabled feedback
await tester.pumpWidget(buildFrame(widgetEnableFeedack: false));
await tester.tap(find.text('Show Menu'));
await tester.pumpAndSettle();
expect(feedback.clickSoundCount, 1);
expect(feedback.hapticCount, 0);
//PopupMenuButton with enabled feedback by default
await tester.pumpWidget(buildFrame());
await tester.tap(find.text('Show Menu'));
await tester.pumpAndSettle();
expect(feedback.clickSoundCount, 2);
expect(feedback.hapticCount, 0);
//PopupMenu with disabled feedback using PopupMenuButtonTheme
await tester.pumpWidget(buildFrame(themeEnableFeedback: false));
await tester.tap(find.text('Show Menu'));
await tester.pumpAndSettle();
expect(feedback.clickSoundCount, 2);
expect(feedback.hapticCount, 0);
//PopupMenu enableFeedback property overrides PopupMenuButtonTheme
await tester.pumpWidget(buildFrame(widgetEnableFeedack: false,themeEnableFeedback: true));
await tester.tap(find.text('Show Menu'));
await tester.pumpAndSettle();
expect(feedback.clickSoundCount, 2);
expect(feedback.hapticCount, 0);
});
});
}
class TestApp extends StatefulWidget {