Add optional haptic feedback on LongPressDraggable (#18781)
This commit is contained in:
parent
a66ea0a628
commit
924c206cf8
@ -267,6 +267,7 @@ class LongPressDraggable<T> extends Draggable<T> {
|
|||||||
VoidCallback onDragStarted,
|
VoidCallback onDragStarted,
|
||||||
DraggableCanceledCallback onDraggableCanceled,
|
DraggableCanceledCallback onDraggableCanceled,
|
||||||
VoidCallback onDragCompleted,
|
VoidCallback onDragCompleted,
|
||||||
|
this.hapticFeedbackOnStart = true,
|
||||||
bool ignoringFeedbackSemantics = true,
|
bool ignoringFeedbackSemantics = true,
|
||||||
}) : super(
|
}) : super(
|
||||||
key: key,
|
key: key,
|
||||||
@ -284,12 +285,15 @@ class LongPressDraggable<T> extends Draggable<T> {
|
|||||||
ignoringFeedbackSemantics: ignoringFeedbackSemantics,
|
ignoringFeedbackSemantics: ignoringFeedbackSemantics,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Whether haptic feedback should be triggered on drag start.
|
||||||
|
final bool hapticFeedbackOnStart;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
DelayedMultiDragGestureRecognizer createRecognizer(GestureMultiDragStartCallback onStart) {
|
DelayedMultiDragGestureRecognizer createRecognizer(GestureMultiDragStartCallback onStart) {
|
||||||
return new DelayedMultiDragGestureRecognizer()
|
return new DelayedMultiDragGestureRecognizer()
|
||||||
..onStart = (Offset position) {
|
..onStart = (Offset position) {
|
||||||
final Drag result = onStart(position);
|
final Drag result = onStart(position);
|
||||||
if (result != null)
|
if (result != null && hapticFeedbackOnStart)
|
||||||
HapticFeedback.vibrate();
|
HapticFeedback.vibrate();
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import 'package:flutter/semantics.dart';
|
import 'package:flutter/semantics.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
|
|
||||||
@ -1635,6 +1636,14 @@ void main() {
|
|||||||
expect(onDragStartedCalled, isTrue);
|
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 {
|
testWidgets('Drag feedback with child anchor positions correctly', (WidgetTester tester) async {
|
||||||
await _testChildAnchorFeedbackPosition(tester: tester);
|
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 {
|
Future<Null> _testChildAnchorFeedbackPosition({WidgetTester tester, double top = 0.0, double left = 0.0}) async {
|
||||||
final List<int> accepted = <int>[];
|
final List<int> accepted = <int>[];
|
||||||
int dragStartedCount = 0;
|
int dragStartedCount = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user