Audit use of defaultTargetPlatform (#36871)
This commit is contained in:
@@ -218,8 +218,18 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
|
||||
void _handleSelectedItemChanged(int index) {
|
||||
// Only the haptic engine hardware on iOS devices would produce the
|
||||
// intended effects.
|
||||
if (defaultTargetPlatform == TargetPlatform.iOS
|
||||
&& index != _lastHapticIndex) {
|
||||
bool hasSuitableHapticHardware;
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
hasSuitableHapticHardware = true;
|
||||
break;
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
hasSuitableHapticHardware = false;
|
||||
break;
|
||||
}
|
||||
assert(hasSuitableHapticHardware != null);
|
||||
if (hasSuitableHapticHardware && index != _lastHapticIndex) {
|
||||
_lastHapticIndex = index;
|
||||
HapticFeedback.selectionClick();
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
|
||||
}
|
||||
|
||||
void _emitVibration() {
|
||||
switch(defaultTargetPlatform) {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
HapticFeedback.lightImpact();
|
||||
break;
|
||||
|
||||
@@ -11,11 +11,11 @@ import '_platform_io.dart'
|
||||
/// This is the default value of [ThemeData.platform] (hence the name). Widgets
|
||||
/// from the material library should use [Theme.of] to determine the current
|
||||
/// platform for styling purposes, rather than using [defaultTargetPlatform].
|
||||
/// However, if there is widget behavior that depends on the actual underlying
|
||||
/// platform, then depending on [defaultTargetPlatform] makes sense.
|
||||
/// [dart.io.Platform.environment] should be used directly only when it's
|
||||
/// critical to actually know the current platform, without any overrides
|
||||
/// possible (for example, when a system API is about to be called).
|
||||
/// Widgets and render objects at lower layers that try to emulate the
|
||||
/// underlying platform can depend on [defaultTargetPlatform] directly. The
|
||||
/// [dart.io.Platform] object should only be used directly when it's critical to
|
||||
/// actually know the current platform, without any overrides possible (for
|
||||
/// example, when a system API is about to be called).
|
||||
///
|
||||
/// In a test environment, the platform returned is [TargetPlatform.android]
|
||||
/// regardless of the host platform. (Android was chosen because the tests were
|
||||
|
||||
@@ -384,11 +384,11 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
@override
|
||||
final Size preferredSize;
|
||||
|
||||
bool _getEffectiveCenterTitle(ThemeData themeData) {
|
||||
bool _getEffectiveCenterTitle(ThemeData theme) {
|
||||
if (centerTitle != null)
|
||||
return centerTitle;
|
||||
assert(themeData.platform != null);
|
||||
switch (themeData.platform) {
|
||||
assert(theme.platform != null);
|
||||
switch (theme.platform) {
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
return false;
|
||||
@@ -417,7 +417,7 @@ class _AppBarState extends State<AppBar> {
|
||||
Widget build(BuildContext context) {
|
||||
assert(!widget.primary || debugCheckHasMediaQuery(context));
|
||||
assert(debugCheckHasMaterialLocalizations(context));
|
||||
final ThemeData themeData = Theme.of(context);
|
||||
final ThemeData theme = Theme.of(context);
|
||||
final AppBarTheme appBarTheme = AppBarTheme.of(context);
|
||||
final ScaffoldState scaffold = Scaffold.of(context, nullOk: true);
|
||||
final ModalRoute<dynamic> parentRoute = ModalRoute.of(context);
|
||||
@@ -429,16 +429,16 @@ class _AppBarState extends State<AppBar> {
|
||||
|
||||
IconThemeData overallIconTheme = widget.iconTheme
|
||||
?? appBarTheme.iconTheme
|
||||
?? themeData.primaryIconTheme;
|
||||
?? theme.primaryIconTheme;
|
||||
IconThemeData actionsIconTheme = widget.actionsIconTheme
|
||||
?? appBarTheme.actionsIconTheme
|
||||
?? overallIconTheme;
|
||||
TextStyle centerStyle = widget.textTheme?.title
|
||||
?? appBarTheme.textTheme?.title
|
||||
?? themeData.primaryTextTheme.title;
|
||||
?? theme.primaryTextTheme.title;
|
||||
TextStyle sideStyle = widget.textTheme?.body1
|
||||
?? appBarTheme.textTheme?.body1
|
||||
?? themeData.primaryTextTheme.body1;
|
||||
?? theme.primaryTextTheme.body1;
|
||||
|
||||
if (widget.toolbarOpacity != 1.0) {
|
||||
final double opacity = const Interval(0.25, 1.0, curve: Curves.fastOutSlowIn).transform(widget.toolbarOpacity);
|
||||
@@ -477,7 +477,7 @@ class _AppBarState extends State<AppBar> {
|
||||
Widget title = widget.title;
|
||||
if (title != null) {
|
||||
bool namesRoute;
|
||||
switch (defaultTargetPlatform) {
|
||||
switch (theme.platform) {
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
namesRoute = true;
|
||||
@@ -524,7 +524,7 @@ class _AppBarState extends State<AppBar> {
|
||||
leading: leading,
|
||||
middle: title,
|
||||
trailing: actions,
|
||||
centerMiddle: widget._getEffectiveCenterTitle(themeData),
|
||||
centerMiddle: widget._getEffectiveCenterTitle(theme),
|
||||
middleSpacing: widget.titleSpacing,
|
||||
);
|
||||
|
||||
@@ -584,7 +584,7 @@ class _AppBarState extends State<AppBar> {
|
||||
}
|
||||
final Brightness brightness = widget.brightness
|
||||
?? appBarTheme.brightness
|
||||
?? themeData.primaryColorBrightness;
|
||||
?? theme.primaryColorBrightness;
|
||||
final SystemUiOverlayStyle overlayStyle = brightness == Brightness.dark
|
||||
? SystemUiOverlayStyle.light
|
||||
: SystemUiOverlayStyle.dark;
|
||||
@@ -596,7 +596,7 @@ class _AppBarState extends State<AppBar> {
|
||||
child: Material(
|
||||
color: widget.backgroundColor
|
||||
?? appBarTheme.color
|
||||
?? themeData.primaryColor,
|
||||
?? theme.primaryColor,
|
||||
elevation: widget.elevation
|
||||
?? appBarTheme.elevation
|
||||
?? _defaultElevation,
|
||||
|
||||
@@ -263,7 +263,7 @@ class _ModalBottomSheet<T> extends StatefulWidget {
|
||||
|
||||
class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
|
||||
String _getRouteLabel(MaterialLocalizations localizations) {
|
||||
switch (defaultTargetPlatform) {
|
||||
switch (Theme.of(context).platform) {
|
||||
case TargetPlatform.iOS:
|
||||
return '';
|
||||
case TargetPlatform.android:
|
||||
|
||||
@@ -319,7 +319,7 @@ class AlertDialog extends StatelessWidget {
|
||||
),
|
||||
));
|
||||
} else {
|
||||
switch (defaultTargetPlatform) {
|
||||
switch (theme.platform) {
|
||||
case TargetPlatform.iOS:
|
||||
label = semanticLabel;
|
||||
break;
|
||||
@@ -587,16 +587,18 @@ class SimpleDialog extends StatelessWidget {
|
||||
final List<Widget> body = <Widget>[];
|
||||
String label = semanticLabel;
|
||||
|
||||
final ThemeData theme = Theme.of(context);
|
||||
|
||||
if (title != null) {
|
||||
body.add(Padding(
|
||||
padding: titlePadding,
|
||||
child: DefaultTextStyle(
|
||||
style: Theme.of(context).textTheme.title,
|
||||
style: theme.textTheme.title,
|
||||
child: Semantics(namesRoute: true, child: title),
|
||||
),
|
||||
));
|
||||
} else {
|
||||
switch (defaultTargetPlatform) {
|
||||
switch (theme.platform) {
|
||||
case TargetPlatform.iOS:
|
||||
label = semanticLabel;
|
||||
break;
|
||||
|
||||
@@ -11,6 +11,7 @@ import 'debug.dart';
|
||||
import 'list_tile.dart';
|
||||
import 'material.dart';
|
||||
import 'material_localizations.dart';
|
||||
import 'theme.dart';
|
||||
|
||||
/// The possible alignments of a [Drawer].
|
||||
enum DrawerAlignment {
|
||||
@@ -125,7 +126,7 @@ class Drawer extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
assert(debugCheckHasMaterialLocalizations(context));
|
||||
String label = semanticLabel;
|
||||
switch (defaultTargetPlatform) {
|
||||
switch (Theme.of(context).platform) {
|
||||
case TargetPlatform.iOS:
|
||||
label = semanticLabel;
|
||||
break;
|
||||
@@ -469,6 +470,17 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
|
||||
),
|
||||
);
|
||||
} else {
|
||||
bool platformHasBackButton;
|
||||
switch (Theme.of(context).platform) {
|
||||
case TargetPlatform.android:
|
||||
platformHasBackButton = true;
|
||||
break;
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.fuchsia:
|
||||
platformHasBackButton = false;
|
||||
break;
|
||||
}
|
||||
assert(platformHasBackButton != null);
|
||||
return GestureDetector(
|
||||
key: _gestureDetectorKey,
|
||||
onHorizontalDragDown: _handleDragDown,
|
||||
@@ -483,7 +495,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
|
||||
BlockSemantics(
|
||||
child: GestureDetector(
|
||||
// On Android, the back button is used to dismiss a modal.
|
||||
excludeFromSemantics: defaultTargetPlatform == TargetPlatform.android,
|
||||
excludeFromSemantics: platformHasBackButton,
|
||||
onTap: close,
|
||||
child: Semantics(
|
||||
label: MaterialLocalizations.of(context)?.modalBarrierDismissLabel,
|
||||
|
||||
@@ -199,8 +199,10 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
|
||||
}
|
||||
|
||||
if (widget.title != null) {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
|
||||
Widget title;
|
||||
switch (defaultTargetPlatform) {
|
||||
switch (theme.platform) {
|
||||
case TargetPlatform.iOS:
|
||||
title = widget.title;
|
||||
break;
|
||||
@@ -212,7 +214,6 @@ class _FlexibleSpaceBarState extends State<FlexibleSpaceBar> {
|
||||
);
|
||||
}
|
||||
|
||||
final ThemeData theme = Theme.of(context);
|
||||
final double opacity = settings.toolbarOpacity;
|
||||
if (opacity > 0.0) {
|
||||
TextStyle titleStyle = theme.primaryTextTheme.title;
|
||||
|
||||
@@ -748,8 +748,9 @@ Future<T> showMenu<T>({
|
||||
assert(position != null);
|
||||
assert(items != null && items.isNotEmpty);
|
||||
assert(debugCheckHasMaterialLocalizations(context));
|
||||
|
||||
String label = semanticLabel;
|
||||
switch (defaultTargetPlatform) {
|
||||
switch (Theme.of(context).platform) {
|
||||
case TargetPlatform.iOS:
|
||||
label = semanticLabel;
|
||||
break;
|
||||
|
||||
@@ -53,10 +53,9 @@ class Scrollbar extends StatefulWidget {
|
||||
|
||||
class _ScrollbarState extends State<Scrollbar> with TickerProviderStateMixin {
|
||||
ScrollbarPainter _materialPainter;
|
||||
TargetPlatform _currentPlatform;
|
||||
TextDirection _textDirection;
|
||||
Color _themeColor;
|
||||
|
||||
bool _useCupertinoScrollbar;
|
||||
AnimationController _fadeoutAnimationController;
|
||||
Animation<double> _fadeoutOpacityAnimation;
|
||||
Timer _fadeoutTimer;
|
||||
@@ -77,35 +76,36 @@ class _ScrollbarState extends State<Scrollbar> with TickerProviderStateMixin {
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
|
||||
assert((() { _useCupertinoScrollbar = null; return true; })());
|
||||
final ThemeData theme = Theme.of(context);
|
||||
_currentPlatform = theme.platform;
|
||||
|
||||
switch (_currentPlatform) {
|
||||
switch (theme.platform) {
|
||||
case TargetPlatform.iOS:
|
||||
// On iOS, stop all local animations. CupertinoScrollbar has its own
|
||||
// animations.
|
||||
_fadeoutTimer?.cancel();
|
||||
_fadeoutTimer = null;
|
||||
_fadeoutAnimationController.reset();
|
||||
_useCupertinoScrollbar = true;
|
||||
break;
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
_themeColor = theme.highlightColor.withOpacity(1.0);
|
||||
_textDirection = Directionality.of(context);
|
||||
_materialPainter = _buildMaterialScrollbarPainter();
|
||||
_useCupertinoScrollbar = false;
|
||||
break;
|
||||
}
|
||||
assert(_useCupertinoScrollbar != null);
|
||||
}
|
||||
|
||||
ScrollbarPainter _buildMaterialScrollbarPainter() {
|
||||
return ScrollbarPainter(
|
||||
color: _themeColor,
|
||||
textDirection: _textDirection,
|
||||
thickness: _kScrollbarThickness,
|
||||
fadeoutOpacityAnimation: _fadeoutOpacityAnimation,
|
||||
padding: MediaQuery.of(context).padding,
|
||||
);
|
||||
color: _themeColor,
|
||||
textDirection: _textDirection,
|
||||
thickness: _kScrollbarThickness,
|
||||
fadeoutOpacityAnimation: _fadeoutOpacityAnimation,
|
||||
padding: MediaQuery.of(context).padding,
|
||||
);
|
||||
}
|
||||
|
||||
bool _handleScrollNotification(ScrollNotification notification) {
|
||||
@@ -116,9 +116,8 @@ class _ScrollbarState extends State<Scrollbar> with TickerProviderStateMixin {
|
||||
|
||||
// iOS sub-delegates to the CupertinoScrollbar instead and doesn't handle
|
||||
// scroll notifications here.
|
||||
if (_currentPlatform != TargetPlatform.iOS
|
||||
&& (notification is ScrollUpdateNotification
|
||||
|| notification is OverscrollNotification)) {
|
||||
if (!_useCupertinoScrollbar &&
|
||||
(notification is ScrollUpdateNotification || notification is OverscrollNotification)) {
|
||||
if (_fadeoutAnimationController.status != AnimationStatus.forward) {
|
||||
_fadeoutAnimationController.forward();
|
||||
}
|
||||
@@ -143,25 +142,21 @@ class _ScrollbarState extends State<Scrollbar> with TickerProviderStateMixin {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
switch (_currentPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
return CupertinoScrollbar(
|
||||
child: widget.child,
|
||||
);
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
return NotificationListener<ScrollNotification>(
|
||||
onNotification: _handleScrollNotification,
|
||||
child: RepaintBoundary(
|
||||
child: CustomPaint(
|
||||
foregroundPainter: _materialPainter,
|
||||
child: RepaintBoundary(
|
||||
child: widget.child,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
if (_useCupertinoScrollbar) {
|
||||
return CupertinoScrollbar(
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
throw FlutterError('Unknown platform for scrollbar insertion');
|
||||
return NotificationListener<ScrollNotification>(
|
||||
onNotification: _handleScrollNotification,
|
||||
child: RepaintBoundary(
|
||||
child: CustomPaint(
|
||||
foregroundPainter: _materialPainter,
|
||||
child: RepaintBoundary(
|
||||
child: widget.child,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,7 +485,7 @@ class _SearchPageState<T> extends State<_SearchPage<T>> {
|
||||
break;
|
||||
}
|
||||
String routeName;
|
||||
switch (defaultTargetPlatform) {
|
||||
switch (theme.platform) {
|
||||
case TargetPlatform.iOS:
|
||||
routeName = '';
|
||||
break;
|
||||
|
||||
@@ -774,14 +774,26 @@ class ThemeData extends Diagnosticable {
|
||||
|
||||
/// The platform the material widgets should adapt to target.
|
||||
///
|
||||
/// Defaults to the current platform. This should be used in order to style UI
|
||||
/// elements according to platform conventions.
|
||||
/// Defaults to the current platform, as exposed by [defaultTargetPlatform].
|
||||
/// This should be used in order to style UI elements according to platform
|
||||
/// conventions.
|
||||
///
|
||||
/// [Platform.defaultTargetPlatform] should be used directly instead only in
|
||||
/// rare cases where it's necessary to determine behavior based on the
|
||||
/// platform. [dart.io.Platform.environment] should be used when it's critical
|
||||
/// Widgets from the material library should use this getter (via [Theme.of])
|
||||
/// to determine the current platform for the purpose of emulating the
|
||||
/// platform behavior (e.g. scrolling or haptic effects). Widgets and render
|
||||
/// objects at lower layers that try to emulate the underlying platform
|
||||
/// platform can depend on [defaultTargetPlatform] directly, or may require
|
||||
/// that the target platform be provided as an argument. The
|
||||
/// [dart.io.Platform] object should only be used directly when it's critical
|
||||
/// to actually know the current platform, without any overrides possible (for
|
||||
/// example, when a system API is about to be called).
|
||||
///
|
||||
/// In a test environment, the platform returned is [TargetPlatform.android]
|
||||
/// regardless of the host platform. (Android was chosen because the tests
|
||||
/// were originally written assuming Android-like behavior, and we added
|
||||
/// platform adaptations for iOS later). Tests can check iOS behavior by
|
||||
/// setting the [platform] of the [Theme] explicitly to [TargetPlatform.iOS],
|
||||
/// or by setting [debugDefaultTargetPlatformOverride].
|
||||
final TargetPlatform platform;
|
||||
|
||||
/// Configures the hit test size of certain Material widgets.
|
||||
|
||||
@@ -203,8 +203,13 @@ class _DayPeriodControl extends StatelessWidget {
|
||||
if (fragmentContext.selectedTime.period == DayPeriod.am) {
|
||||
return;
|
||||
}
|
||||
if (fragmentContext.targetPlatform == TargetPlatform.android) {
|
||||
_announceToAccessibility(context, MaterialLocalizations.of(context).anteMeridiemAbbreviation);
|
||||
switch (fragmentContext.targetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
_announceToAccessibility(context, MaterialLocalizations.of(context).anteMeridiemAbbreviation);
|
||||
break;
|
||||
case TargetPlatform.iOS:
|
||||
break;
|
||||
}
|
||||
_togglePeriod();
|
||||
}
|
||||
@@ -213,8 +218,13 @@ class _DayPeriodControl extends StatelessWidget {
|
||||
if (fragmentContext.selectedTime.period == DayPeriod.pm) {
|
||||
return;
|
||||
}
|
||||
if (fragmentContext.targetPlatform == TargetPlatform.android) {
|
||||
_announceToAccessibility(context, MaterialLocalizations.of(context).postMeridiemAbbreviation);
|
||||
switch (fragmentContext.targetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
_announceToAccessibility(context, MaterialLocalizations.of(context).postMeridiemAbbreviation);
|
||||
break;
|
||||
case TargetPlatform.iOS:
|
||||
break;
|
||||
}
|
||||
_togglePeriod();
|
||||
}
|
||||
|
||||
@@ -391,13 +391,8 @@ class RenderEditable extends RenderBox {
|
||||
// TODO(goderbauer): doesn't handle extended grapheme clusters with more than one Unicode scalar value (https://github.com/flutter/flutter/issues/13404).
|
||||
void _handleKeyEvent(RawKeyEvent keyEvent) {
|
||||
// Only handle key events on Android.
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
break;
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.fuchsia:
|
||||
return;
|
||||
}
|
||||
if (keyEvent.data is! RawKeyEventDataAndroid)
|
||||
return;
|
||||
|
||||
if (keyEvent is RawKeyUpEvent)
|
||||
return;
|
||||
@@ -1594,12 +1589,15 @@ class RenderEditable extends RenderBox {
|
||||
/// of the cursor for iOS is approximate and obtained through an eyeball
|
||||
/// comparison.
|
||||
Rect get _getCaretPrototype {
|
||||
switch(defaultTargetPlatform){
|
||||
assert(defaultTargetPlatform != null);
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
return Rect.fromLTWH(0.0, 0.0, cursorWidth, preferredLineHeight + 2);
|
||||
default:
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
return Rect.fromLTWH(0.0, _kCaretHeightOffset, cursorWidth, preferredLineHeight - 2.0 * _kCaretHeightOffset);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@override
|
||||
void performLayout() {
|
||||
@@ -1647,10 +1645,11 @@ class RenderEditable extends RenderBox {
|
||||
if (_cursorOffset != null)
|
||||
caretRect = caretRect.shift(_cursorOffset);
|
||||
|
||||
if (_textPainter.getFullHeightForCaret(textPosition, _caretPrototype) != null) {
|
||||
final double caretHeight = _textPainter.getFullHeightForCaret(textPosition, _caretPrototype);
|
||||
if (caretHeight != null) {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS: {
|
||||
final double heightDiff = _textPainter.getFullHeightForCaret(textPosition, _caretPrototype) - caretRect.height;
|
||||
case TargetPlatform.iOS:
|
||||
final double heightDiff = caretHeight - caretRect.height;
|
||||
// Center the caret vertically along the text.
|
||||
caretRect = Rect.fromLTWH(
|
||||
caretRect.left,
|
||||
@@ -1659,8 +1658,8 @@ class RenderEditable extends RenderBox {
|
||||
caretRect.height,
|
||||
);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
// Override the height to take the full height of the glyph at the TextPosition
|
||||
// when not on iOS. iOS has special handling that creates a taller caret.
|
||||
// TODO(garyq): See the TODO for _getCaretPrototype.
|
||||
@@ -1668,10 +1667,9 @@ class RenderEditable extends RenderBox {
|
||||
caretRect.left,
|
||||
caretRect.top - _kCaretHeightOffset,
|
||||
caretRect.width,
|
||||
_textPainter.getFullHeightForCaret(textPosition, _caretPrototype),
|
||||
caretHeight,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,18 @@ class ModalBarrier extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
assert(!dismissible || semanticsLabel == null || debugCheckHasDirectionality(context));
|
||||
final bool semanticsDismissible = dismissible && defaultTargetPlatform != TargetPlatform.android;
|
||||
bool platformSupportsDismissingBarrier;
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
platformSupportsDismissingBarrier = false;
|
||||
break;
|
||||
case TargetPlatform.iOS:
|
||||
platformSupportsDismissingBarrier = true;
|
||||
break;
|
||||
}
|
||||
assert(platformSupportsDismissingBarrier != null);
|
||||
final bool semanticsDismissible = dismissible && platformSupportsDismissingBarrier;
|
||||
final bool modalBarrierSemanticsDismissible = barrierSemanticsDismissible ?? semanticsDismissible;
|
||||
return BlockSemantics(
|
||||
child: ExcludeSemantics(
|
||||
|
||||
Reference in New Issue
Block a user