Add optional haptic feedback on LongPressDraggable (#18781)

This commit is contained in:
Alex Allen 2018-07-19 20:21:40 -07:00 committed by xster
parent a66ea0a628
commit 924c206cf8
2 changed files with 56 additions and 1 deletions

View File

@ -267,6 +267,7 @@ class LongPressDraggable<T> extends Draggable<T> {
VoidCallback onDragStarted,
DraggableCanceledCallback onDraggableCanceled,
VoidCallback onDragCompleted,
this.hapticFeedbackOnStart = true,
bool ignoringFeedbackSemantics = true,
}) : super(
key: key,
@ -284,12 +285,15 @@ class LongPressDraggable<T> extends Draggable<T> {
ignoringFeedbackSemantics: ignoringFeedbackSemantics,
);
/// Whether haptic feedback should be triggered on drag start.
final bool hapticFeedbackOnStart;
@override
DelayedMultiDragGestureRecognizer createRecognizer(GestureMultiDragStartCallback onStart) {
return new DelayedMultiDragGestureRecognizer()
..onStart = (Offset position) {
final Drag result = onStart(position);
if (result != null)
if (result != null && hapticFeedbackOnStart)
HapticFeedback.vibrate();
return result;
};

View File

@ -4,6 +4,7 @@
import 'package:flutter/semantics.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
@ -1635,6 +1636,14 @@ void main() {
expect(onDragStartedCalled, isTrue);
});
testWidgets('long-press draggable calls Haptic Feedback onStart', (WidgetTester tester) async {
await _testLongPressDraggableHapticFeedback(tester: tester, hapticFeedbackOnStart: true, expectedHapticFeedbackCount: 1);
});
testWidgets('long-press draggable can disable Haptic Feedback', (WidgetTester tester) async {
await _testLongPressDraggableHapticFeedback(tester: tester, hapticFeedbackOnStart: false, expectedHapticFeedbackCount: 0);
});
testWidgets('Drag feedback with child anchor positions correctly', (WidgetTester tester) async {
await _testChildAnchorFeedbackPosition(tester: tester);
});
@ -1793,6 +1802,48 @@ void main() {
}
Future<Null> _testLongPressDraggableHapticFeedback({WidgetTester tester, bool hapticFeedbackOnStart, int expectedHapticFeedbackCount}) async {
bool onDragStartedCalled = false;
int hapticFeedbackCalls = 0;
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'HapticFeedback.vibrate') {
hapticFeedbackCalls++;
}
});
await tester.pumpWidget(new MaterialApp(
home: new LongPressDraggable<int>(
data: 1,
child: const Text('Source'),
feedback: const Text('Dragging'),
hapticFeedbackOnStart: hapticFeedbackOnStart,
onDragStarted: () {
onDragStartedCalled = true;
},
),
));
expect(find.text('Source'), findsOneWidget);
expect(find.text('Dragging'), findsNothing);
expect(onDragStartedCalled, isFalse);
final Offset firstLocation = tester.getCenter(find.text('Source'));
await tester.startGesture(firstLocation, pointer: 7);
await tester.pump();
expect(find.text('Source'), findsOneWidget);
expect(find.text('Dragging'), findsNothing);
expect(onDragStartedCalled, isFalse);
await tester.pump(kLongPressTimeout);
expect(find.text('Source'), findsOneWidget);
expect(find.text('Dragging'), findsOneWidget);
expect(onDragStartedCalled, isTrue);
expect(hapticFeedbackCalls, expectedHapticFeedbackCount);
}
Future<Null> _testChildAnchorFeedbackPosition({WidgetTester tester, double top = 0.0, double left = 0.0}) async {
final List<int> accepted = <int>[];
int dragStartedCount = 0;