Unverified Commit d1187487 authored by Chinmoy's avatar Chinmoy Committed by GitHub

Added enableFeedback property to FloatingActionButton (#69826)

parent 02efffc1
......@@ -147,6 +147,7 @@ class FloatingActionButton extends StatelessWidget {
this.autofocus = false,
this.materialTapTargetSize,
this.isExtended = false,
this.enableFeedback,
}) : assert(elevation == null || elevation >= 0.0),
assert(focusElevation == null || focusElevation >= 0.0),
assert(hoverElevation == null || hoverElevation >= 0.0),
......@@ -189,6 +190,7 @@ class FloatingActionButton extends StatelessWidget {
this.autofocus = false,
Widget? icon,
required Widget label,
this.enableFeedback,
}) : assert(elevation == null || elevation >= 0.0),
assert(focusElevation == null || focusElevation >= 0.0),
assert(hoverElevation == null || hoverElevation >= 0.0),
......@@ -409,6 +411,19 @@ class FloatingActionButton extends StatelessWidget {
/// * [MaterialTapTargetSize], for a description of how this affects tap targets.
final MaterialTapTargetSize? materialTapTargetSize;
/// 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.
///
/// If null, [FloatingActionButtonThemeData.enableFeedback] is used.
/// If both are null, then default value is true.
///
/// See also:
///
/// * [Feedback] for providing platform-specific feedback to certain actions.
final bool? enableFeedback;
final BoxConstraints _sizeConstraints;
static const double _defaultElevation = 6;
......@@ -455,6 +470,8 @@ class FloatingActionButton extends StatelessWidget {
?? _defaultHighlightElevation;
final MaterialTapTargetSize materialTapTargetSize = this.materialTapTargetSize
?? theme.materialTapTargetSize;
final bool enableFeedback = this.enableFeedback
?? floatingActionButtonTheme.enableFeedback ?? true;
final TextStyle textStyle = theme.textTheme.button!.copyWith(
color: foregroundColor,
letterSpacing: 1.2,
......@@ -483,6 +500,7 @@ class FloatingActionButton extends StatelessWidget {
focusNode: focusNode,
autofocus: autofocus,
child: child,
enableFeedback: enableFeedback,
);
if (tooltip != null) {
......
......@@ -42,6 +42,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
this.disabledElevation,
this.highlightElevation,
this.shape,
this.enableFeedback,
});
/// Color to be used for the unselected, enabled [FloatingActionButton]'s
......@@ -89,6 +90,12 @@ class FloatingActionButtonThemeData with Diagnosticable {
/// The shape to be used for the floating action button's [Material].
final ShapeBorder? shape;
/// If specified, defines the feedback property for [FloatingActionButton].
///
/// If [FloatingActionButton.enableFeedback] is provided, [enableFeedback] is
/// ignored.
final bool? enableFeedback;
/// Creates a copy of this object with the given fields replaced with the
/// new values.
FloatingActionButtonThemeData copyWith({
......@@ -103,6 +110,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
double? disabledElevation,
double? highlightElevation,
ShapeBorder? shape,
bool? enableFeedback,
}) {
return FloatingActionButtonThemeData(
foregroundColor: foregroundColor ?? this.foregroundColor,
......@@ -116,6 +124,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
disabledElevation: disabledElevation ?? this.disabledElevation,
highlightElevation: highlightElevation ?? this.highlightElevation,
shape: shape ?? this.shape,
enableFeedback: enableFeedback ?? this.enableFeedback,
);
}
......@@ -140,6 +149,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
disabledElevation: lerpDouble(a?.disabledElevation, b?.disabledElevation, t),
highlightElevation: lerpDouble(a?.highlightElevation, b?.highlightElevation, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
enableFeedback: t < 0.5 ? a?.enableFeedback : b?.enableFeedback,
);
}
......@@ -157,6 +167,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
disabledElevation,
highlightElevation,
shape,
enableFeedback,
);
}
......@@ -177,7 +188,8 @@ class FloatingActionButtonThemeData with Diagnosticable {
&& other.hoverElevation == hoverElevation
&& other.disabledElevation == disabledElevation
&& other.highlightElevation == highlightElevation
&& other.shape == shape;
&& other.shape == shape
&& other.enableFeedback == enableFeedback;
}
@override
......@@ -196,5 +208,6 @@ class FloatingActionButtonThemeData with Diagnosticable {
properties.add(DoubleProperty('disabledElevation', disabledElevation, defaultValue: defaultData.disabledElevation));
properties.add(DoubleProperty('highlightElevation', highlightElevation, defaultValue: defaultData.highlightElevation));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: defaultData.shape));
properties.add(DiagnosticsProperty<bool>('enableFeedback', enableFeedback, defaultValue: defaultData.enableFeedback));
}
}
......@@ -11,6 +11,7 @@ import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart';
import '../widgets/semantics_tester.dart';
import 'feedback_tester.dart';
void main() {
testWidgets('Floating Action Button control test', (WidgetTester tester) async {
......@@ -963,6 +964,116 @@ void main() {
expect(find.byKey(iconKey), findsOneWidget);
expect(find.byKey(labelKey), findsNothing);
});
group('feedback', () {
late FeedbackTester feedback;
setUp(() {
feedback = FeedbackTester();
});
tearDown(() {
feedback.dispose();
});
testWidgets('FloatingActionButton with enabled feedback', (WidgetTester tester) async {
const bool enableFeedback = true;
await tester.pumpWidget(MaterialApp(
home: FloatingActionButton(
onPressed: () {},
enableFeedback: enableFeedback,
child: const Icon(Icons.access_alarm),
),
));
await tester.tap(find.byType(RawMaterialButton));
await tester.pump(const Duration(seconds: 1));
expect(feedback.clickSoundCount, 1);
expect(feedback.hapticCount, 0);
});
testWidgets('FloatingActionButton with disabled feedback', (WidgetTester tester) async {
const bool enableFeedback = false;
await tester.pumpWidget(MaterialApp(
home: FloatingActionButton(
onPressed: () {},
enableFeedback: enableFeedback,
child: const Icon(Icons.access_alarm),
),
));
await tester.tap(find.byType(RawMaterialButton));
await tester.pump(const Duration(seconds: 1));
expect(feedback.clickSoundCount, 0);
expect(feedback.hapticCount, 0);
});
testWidgets('FloatingActionButton with enabled feedback by default', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.access_alarm),
),
));
await tester.tap(find.byType(RawMaterialButton));
await tester.pump(const Duration(seconds: 1));
expect(feedback.clickSoundCount, 1);
expect(feedback.hapticCount, 0);
});
testWidgets('FloatingActionButton with disabled feedback using FloatingActionButtonTheme', (WidgetTester tester) async {
const bool enableFeedbackTheme = false;
final ThemeData theme = ThemeData(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
enableFeedback: enableFeedbackTheme,
),
);
await tester.pumpWidget(MaterialApp(
home: Theme(
data: theme,
child: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.access_alarm),
),
),
));
await tester.tap(find.byType(RawMaterialButton));
await tester.pump(const Duration(seconds: 1));
expect(feedback.clickSoundCount, 0);
expect(feedback.hapticCount, 0);
});
testWidgets('FloatingActionButton.enableFeedback is overriden by FloatingActionButtonThemeData.enableFeedback', (WidgetTester tester) async {
const bool enableFeedbackTheme = false;
const bool enableFeedback = true;
final ThemeData theme = ThemeData(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
enableFeedback: enableFeedbackTheme,
),
);
await tester.pumpWidget(MaterialApp(
home: Theme(
data: theme,
child: FloatingActionButton(
enableFeedback: enableFeedback,
onPressed: () {},
child: const Icon(Icons.access_alarm),
),
),
));
await tester.tap(find.byType(RawMaterialButton));
await tester.pump(const Duration(seconds: 1));
expect(feedback.clickSoundCount, 1);
expect(feedback.hapticCount, 0);
});
});
}
Offset _rightEdgeOfFab(WidgetTester tester) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment