forked from firka/flutter
Add enableFeedback param to MaterialButton, RawMaterialButton and IconButton (#41972)
* Wire enableFeedback parameter through MaterialButton, RawMaterialButton, and IconButton. Co-Authored-By: Shi-Hao Hong <shihaohong@google.com>
This commit is contained in:
committed by
Shi-Hao Hong
parent
2e7d9130b2
commit
fbabb264e0
@@ -60,6 +60,7 @@ class RawMaterialButton extends StatefulWidget {
|
||||
this.autofocus = false,
|
||||
MaterialTapTargetSize materialTapTargetSize,
|
||||
this.child,
|
||||
this.enableFeedback = true,
|
||||
}) : materialTapTargetSize = materialTapTargetSize ?? MaterialTapTargetSize.padded,
|
||||
assert(shape != null),
|
||||
assert(elevation != null && elevation >= 0.0),
|
||||
@@ -259,6 +260,16 @@ class RawMaterialButton extends StatefulWidget {
|
||||
/// Defaults to [Clip.none], and must not be null.
|
||||
final Clip clipBehavior;
|
||||
|
||||
/// 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
|
||||
_RawMaterialButtonState createState() => _RawMaterialButtonState();
|
||||
}
|
||||
@@ -367,6 +378,7 @@ class _RawMaterialButtonState extends State<RawMaterialButton> {
|
||||
onHover: _handleHoveredChanged,
|
||||
onTap: widget.onPressed,
|
||||
onLongPress: widget.onLongPress,
|
||||
enableFeedback: widget.enableFeedback,
|
||||
customBorder: effectiveShape,
|
||||
child: IconTheme.merge(
|
||||
data: IconThemeData(color: effectiveTextColor),
|
||||
|
||||
@@ -151,6 +151,7 @@ class IconButton extends StatelessWidget {
|
||||
this.focusNode,
|
||||
this.autofocus = false,
|
||||
this.tooltip,
|
||||
this.enableFeedback = true,
|
||||
}) : assert(iconSize != null),
|
||||
assert(padding != null),
|
||||
assert(alignment != null),
|
||||
@@ -269,6 +270,16 @@ class IconButton extends StatelessWidget {
|
||||
/// used for accessibility.
|
||||
final String tooltip;
|
||||
|
||||
/// 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
|
||||
Widget build(BuildContext context) {
|
||||
assert(debugCheckHasMaterial(context));
|
||||
@@ -314,6 +325,7 @@ class IconButton extends StatelessWidget {
|
||||
autofocus: autofocus,
|
||||
canRequestFocus: onPressed != null,
|
||||
onTap: onPressed,
|
||||
enableFeedback: enableFeedback,
|
||||
child: result,
|
||||
focusColor: focusColor ?? Theme.of(context).focusColor,
|
||||
hoverColor: hoverColor ?? Theme.of(context).hoverColor,
|
||||
|
||||
@@ -77,6 +77,7 @@ class MaterialButton extends StatelessWidget {
|
||||
this.animationDuration,
|
||||
this.minWidth,
|
||||
this.height,
|
||||
this.enableFeedback = true,
|
||||
this.child,
|
||||
}) : assert(clipBehavior != null),
|
||||
assert(autofocus != null),
|
||||
@@ -355,6 +356,16 @@ class MaterialButton extends StatelessWidget {
|
||||
/// Defaults to the value from the current [ButtonTheme].
|
||||
final double height;
|
||||
|
||||
/// 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
|
||||
Widget build(BuildContext context) {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
@@ -363,6 +374,7 @@ class MaterialButton extends StatelessWidget {
|
||||
return RawMaterialButton(
|
||||
onPressed: onPressed,
|
||||
onLongPress: onLongPress,
|
||||
enableFeedback: enableFeedback,
|
||||
onHighlightChanged: onHighlightChanged,
|
||||
fillColor: buttonTheme.getFillColor(this),
|
||||
textStyle: theme.textTheme.button.copyWith(color: buttonTheme.getTextColor(this)),
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../rendering/mock_canvas.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
import 'feedback_tester.dart';
|
||||
|
||||
class MockOnPressedFunction implements Function {
|
||||
int called = 0;
|
||||
@@ -398,6 +399,74 @@ void main() {
|
||||
expect(focusNode1.hasPrimaryFocus, isTrue);
|
||||
expect(focusNode2.hasPrimaryFocus, isFalse);
|
||||
});
|
||||
|
||||
group('feedback', () {
|
||||
FeedbackTester feedback;
|
||||
|
||||
setUp(() {
|
||||
feedback = FeedbackTester();
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
feedback?.dispose();
|
||||
});
|
||||
|
||||
testWidgets('IconButton with disabled feedback', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(Material(
|
||||
child: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Center(
|
||||
child: IconButton(
|
||||
onPressed: () {},
|
||||
enableFeedback: false,
|
||||
icon: const Icon(Icons.link),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
await tester.tap(find.byType(IconButton), pointer: 1);
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(feedback.clickSoundCount, 0);
|
||||
expect(feedback.hapticCount, 0);
|
||||
});
|
||||
|
||||
testWidgets('IconButton with enabled feedback', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(Material(
|
||||
child: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Center(
|
||||
child: IconButton(
|
||||
onPressed: () {},
|
||||
enableFeedback: true,
|
||||
icon: const Icon(Icons.link),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
await tester.tap(find.byType(IconButton), pointer: 1);
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(feedback.clickSoundCount, 1);
|
||||
expect(feedback.hapticCount, 0);
|
||||
});
|
||||
|
||||
testWidgets('IconButton with enabled feedback by default', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(Material(
|
||||
child: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Center(
|
||||
child: IconButton(
|
||||
onPressed: () {},
|
||||
icon: const Icon(Icons.link),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
await tester.tap(find.byType(IconButton), pointer: 1);
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(feedback.clickSoundCount, 1);
|
||||
expect(feedback.hapticCount, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Widget wrap({ Widget child }) {
|
||||
|
||||
Reference in New Issue
Block a user