Unverified Commit f0480236 authored by xster's avatar xster Committed by GitHub

Cupertino picker haptic (#14831)

* Add selection haptic feedback to Cupertino Pickers

* review

* don't haptic on android
parent 86be138d
...@@ -60,8 +60,9 @@ class _CupertinoPickerDemoState extends State<CupertinoPickerDemo> { ...@@ -60,8 +60,9 @@ class _CupertinoPickerDemoState extends State<CupertinoPickerDemo> {
final FixedExtentScrollController scrollController = final FixedExtentScrollController scrollController =
new FixedExtentScrollController(initialItem: _selectedItemIndex); new FixedExtentScrollController(initialItem: _selectedItemIndex);
return new SizedBox( return new Container(
height: _kPickerSheetHeight, height: _kPickerSheetHeight,
color: CupertinoColors.white,
child: new DefaultTextStyle( child: new DefaultTextStyle(
style: const TextStyle( style: const TextStyle(
color: CupertinoColors.black, color: CupertinoColors.black,
...@@ -70,20 +71,22 @@ class _CupertinoPickerDemoState extends State<CupertinoPickerDemo> { ...@@ -70,20 +71,22 @@ class _CupertinoPickerDemoState extends State<CupertinoPickerDemo> {
child: new GestureDetector( child: new GestureDetector(
// Blocks taps from propagating to the modal sheet and popping. // Blocks taps from propagating to the modal sheet and popping.
onTap: () {}, onTap: () {},
child: new CupertinoPicker( child: new SafeArea(
scrollController: scrollController, child: new CupertinoPicker(
itemExtent: _kPickerItemHeight, scrollController: scrollController,
backgroundColor: CupertinoColors.white, itemExtent: _kPickerItemHeight,
onSelectedItemChanged: (int index) { backgroundColor: CupertinoColors.white,
setState(() { onSelectedItemChanged: (int index) {
_selectedItemIndex = index; setState(() {
}); _selectedItemIndex = index;
}, });
children: new List<Widget>.generate(coolColorNames.length, (int index) { },
return new Center(child: children: new List<Widget>.generate(coolColorNames.length, (int index) {
new Text(coolColorNames[index]), return new Center(child:
); new Text(coolColorNames[index]),
}), );
}),
),
), ),
), ),
), ),
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
/// Color of the 'magnifier' lens border. /// Color of the 'magnifier' lens border.
...@@ -99,10 +100,12 @@ class _CupertinoPickerState extends State<CupertinoPicker> { ...@@ -99,10 +100,12 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
int _lastHapticIndex; int _lastHapticIndex;
void _handleSelectedItemChanged(int index) { void _handleSelectedItemChanged(int index) {
if (index != _lastHapticIndex) { // Only the haptic engine hardware on iOS devices would produce the
// TODO(xster): Insert haptic feedback with lighter knock. // intended effects.
// https://github.com/flutter/flutter/issues/13710. if (defaultTargetPlatform == TargetPlatform.iOS
&& index != _lastHapticIndex) {
_lastHapticIndex = index; _lastHapticIndex = index;
HapticFeedback.selectionClick();
} }
if (widget.onSelectedItemChanged != null) { if (widget.onSelectedItemChanged != null) {
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
...@@ -56,6 +57,99 @@ void main() { ...@@ -56,6 +57,99 @@ void main() {
}); });
group('scroll', () { group('scroll', () {
testWidgets(
'scrolling calls onSelectedItemChanged and triggers haptic feedback',
(WidgetTester tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
final List<int> selectedItems = <int>[];
final List<MethodCall> systemCalls = <MethodCall>[];
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
systemCalls.add(methodCall);
});
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new CupertinoPicker(
itemExtent: 100.0,
onSelectedItemChanged: (int index) { selectedItems.add(index); },
children: new List<Widget>.generate(100, (int index) {
return new Center(
child: new Container(
width: 400.0,
height: 100.0,
child: new Text(index.toString()),
),
);
}),
),
),
);
await tester.drag(find.text('0'), const Offset(0.0, -100.0));
expect(selectedItems, <int>[1]);
expect(
systemCalls.single,
isMethodCall(
'HapticFeedback.vibrate',
arguments: 'HapticFeedbackType.selectionClick',
),
);
await tester.drag(find.text('0'), const Offset(0.0, 100.0));
expect(selectedItems, <int>[1, 0]);
expect(systemCalls, hasLength(2));
expect(
systemCalls.last,
isMethodCall(
'HapticFeedback.vibrate',
arguments: 'HapticFeedbackType.selectionClick',
),
);
debugDefaultTargetPlatformOverride = null;
},
);
testWidgets(
'do not trigger haptic effects on non-iOS devices',
(WidgetTester tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.android;
final List<int> selectedItems = <int>[];
final List<MethodCall> systemCalls = <MethodCall>[];
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
systemCalls.add(methodCall);
});
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new CupertinoPicker(
itemExtent: 100.0,
onSelectedItemChanged: (int index) { selectedItems.add(index); },
children: new List<Widget>.generate(100, (int index) {
return new Center(
child: new Container(
width: 400.0,
height: 100.0,
child: new Text(index.toString()),
),
);
}),
),
),
);
await tester.drag(find.text('0'), const Offset(0.0, -100.0));
expect(selectedItems, <int>[1]);
expect(systemCalls, isEmpty);
debugDefaultTargetPlatformOverride = null;
},
);
testWidgets('a drag in between items settles back', (WidgetTester tester) async { testWidgets('a drag in between items settles back', (WidgetTester tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.iOS; debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
final FixedExtentScrollController controller = final FixedExtentScrollController controller =
......
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