mirror of
https://github.com/flutter/flutter
synced 2024-10-14 04:02:56 +00:00
Add support for system alert sound (#62086)
* Add SystemSoundType.alert (supported in the engine in flutter/engine#19970) * Play system alert sound when user tries to dismiss a non-dismissable modal barrier
This commit is contained in:
parent
7782845edd
commit
6e252772d1
|
@ -9,9 +9,19 @@ import 'dart:async';
|
|||
import 'system_channels.dart';
|
||||
|
||||
/// A sound provided by the system.
|
||||
///
|
||||
/// These sounds may be played with [SystemSound.play].
|
||||
enum SystemSoundType {
|
||||
/// A short indication that a button was pressed.
|
||||
click,
|
||||
|
||||
/// A short system alert sound indicating the need for user attention.
|
||||
///
|
||||
/// Desktop platforms are the only platforms that support a system alert
|
||||
/// sound, so on mobile platforms (Android, iOS), this will be ignored. The
|
||||
/// web platform does not support playing any sounds, so this will be
|
||||
/// ignored on the web as well.
|
||||
alert,
|
||||
}
|
||||
|
||||
/// Provides access to the library of short system specific sounds for common
|
||||
|
@ -24,6 +34,9 @@ class SystemSound {
|
|||
|
||||
/// Play the specified system sound. If that sound is not present on the
|
||||
/// system, the call is ignored.
|
||||
///
|
||||
/// The web platform currently does not support playing sounds, so this call
|
||||
/// will yield no behavior on that platform.
|
||||
static Future<void> play(SystemSoundType type) async {
|
||||
await SystemChannels.platform.invokeMethod<void>(
|
||||
'SystemSound.play',
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'basic.dart';
|
||||
import 'container.dart';
|
||||
|
@ -103,6 +104,8 @@ class ModalBarrier extends StatelessWidget {
|
|||
onDismiss: () {
|
||||
if (dismissible)
|
||||
Navigator.maybePop(context);
|
||||
else
|
||||
SystemSound.play(SystemSoundType.alert);
|
||||
},
|
||||
child: Semantics(
|
||||
label: semanticsDismissible ? semanticsLabel : null,
|
||||
|
|
|
@ -8,6 +8,7 @@ import 'package:flutter_test/flutter_test.dart';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter/gestures.dart' show kSecondaryButton, PointerDeviceKind;
|
||||
|
||||
|
@ -165,6 +166,32 @@ void main() {
|
|||
hovered = false;
|
||||
});
|
||||
|
||||
testWidgets('ModalBarrier plays system alert sound when user tries to dismiss it', (WidgetTester tester) async {
|
||||
final List<String> playedSystemSounds = <String>[];
|
||||
try {
|
||||
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||
if (methodCall.method == 'SystemSound.play')
|
||||
playedSystemSounds.add(methodCall.arguments as String);
|
||||
});
|
||||
|
||||
final Widget subject = Stack(
|
||||
textDirection: TextDirection.ltr,
|
||||
children: <Widget>[
|
||||
tapTarget,
|
||||
const ModalBarrier(dismissible: false),
|
||||
],
|
||||
);
|
||||
|
||||
await tester.pumpWidget(subject);
|
||||
await tester.tap(find.text('target'));
|
||||
await tester.pumpWidget(subject);
|
||||
} finally {
|
||||
SystemChannels.platform.setMockMethodCallHandler(null);
|
||||
}
|
||||
expect(playedSystemSounds, hasLength(1));
|
||||
expect(playedSystemSounds[0], SystemSoundType.alert.toString());
|
||||
});
|
||||
|
||||
testWidgets('ModalBarrier pops the Navigator when dismissed by primary tap', (WidgetTester tester) async {
|
||||
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
|
||||
'/': (BuildContext context) => const FirstWidget(),
|
||||
|
|
Loading…
Reference in a new issue