| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'package:flutter/foundation.dart'; |
| |
| import 'basic.dart'; |
| import 'container.dart'; |
| import 'debug.dart'; |
| import 'framework.dart'; |
| import 'gesture_detector.dart'; |
| import 'navigator.dart'; |
| import 'transitions.dart'; |
| |
| /// A widget that prevents the user from interacting with widgets behind itself. |
| /// |
| /// The modal barrier is the scrim that is rendered behind each route, which |
| /// generally prevents the user from interacting with the route below the |
| /// current route, and normally partially obscures such routes. |
| /// |
| /// For example, when a dialog is on the screen, the page below the dialog is |
| /// usually darkened by the modal barrier. |
| /// |
| /// See also: |
| /// |
| /// * [ModalRoute], which indirectly uses this widget. |
| /// * [AnimatedModalBarrier], which is similar but takes an animated [color] |
| /// instead of a single color value. |
| class ModalBarrier extends StatelessWidget { |
| /// Creates a widget that blocks user interaction. |
| const ModalBarrier({ |
| Key key, |
| this.color, |
| this.dismissible: true, |
| this.semanticsLabel, |
| }) : super(key: key); |
| |
| /// If non-null, fill the barrier with this color. |
| /// |
| /// See also: |
| /// |
| /// * [ModalRoute.barrierColor], which controls this property for the |
| /// [ModalBarrier] built by [ModalRoute] pages. |
| final Color color; |
| |
| /// Whether touching the barrier will pop the current route off the [Navigator]. |
| /// |
| /// See also: |
| /// |
| /// * [ModalRoute.barrierDismissible], which controls this property for the |
| /// [ModalBarrier] built by [ModalRoute] pages. |
| final bool dismissible; |
| |
| /// Semantics label used for the barrier if it is [dismissable]. |
| /// |
| /// The semantics label is read out by accessibility tools (e.g. TalkBack |
| /// on Android and VoiceOver on iOS) when the barrier is focused. |
| /// |
| /// See also: |
| /// |
| /// * [ModalRoute.barrierLabel], which controls this property for the |
| /// [ModalBarrier] built by [ModalRoute] pages. |
| final String semanticsLabel; |
| |
| @override |
| Widget build(BuildContext context) { |
| assert(!dismissible || semanticsLabel == null || debugCheckHasDirectionality(context)); |
| final bool semanticsDismissible = dismissible && defaultTargetPlatform != TargetPlatform.android; |
| return new BlockSemantics( |
| child: new ExcludeSemantics( |
| // On Android, the back button is used to dismiss a modal. |
| excluding: !semanticsDismissible, |
| child: new GestureDetector( |
| onTapDown: (TapDownDetails details) { |
| if (dismissible) |
| Navigator.pop(context); |
| }, |
| behavior: HitTestBehavior.opaque, |
| child: new Semantics( |
| label: semanticsDismissible ? semanticsLabel : null, |
| textDirection: semanticsDismissible && semanticsLabel != null ? Directionality.of(context) : null, |
| child: new ConstrainedBox( |
| constraints: const BoxConstraints.expand(), |
| child: color == null ? null : new DecoratedBox( |
| decoration: new BoxDecoration( |
| color: color |
| ) |
| ) |
| ) |
| ) |
| ) |
| ) |
| ); |
| } |
| } |
| |
| /// A widget that prevents the user from interacting with widgets behind itself, |
| /// and can be configured with an animated color value. |
| /// |
| /// The modal barrier is the scrim that is rendered behind each route, which |
| /// generally prevents the user from interacting with the route below the |
| /// current route, and normally partially obscures such routes. |
| /// |
| /// For example, when a dialog is on the screen, the page below the dialog is |
| /// usually darkened by the modal barrier. |
| /// |
| /// This widget is similar to [ModalBarrier] except that it takes an animated |
| /// [color] instead of a single color. |
| /// |
| /// See also: |
| /// |
| /// * [ModalRoute], which uses this widget. |
| class AnimatedModalBarrier extends AnimatedWidget { |
| /// Creates a widget that blocks user interaction. |
| const AnimatedModalBarrier({ |
| Key key, |
| Animation<Color> color, |
| this.dismissible: true, |
| this.semanticsLabel, |
| }) : super(key: key, listenable: color); |
| |
| /// If non-null, fill the barrier with this color. |
| /// |
| /// See also: |
| /// |
| /// * [ModalRoute.barrierColor], which controls this property for the |
| /// [AnimatedModalBarrier] built by [ModalRoute] pages. |
| Animation<Color> get color => listenable; |
| |
| /// Whether touching the barrier will pop the current route off the [Navigator]. |
| /// |
| /// See also: |
| /// |
| /// * [ModalRoute.barrierDismissible], which controls this property for the |
| /// [AnimatedModalBarrier] built by [ModalRoute] pages. |
| final bool dismissible; |
| |
| /// Semantics label used for the barrier if it is [dismissable]. |
| /// |
| /// The semantics label is read out by accessibility tools (e.g. TalkBack |
| /// on Android and VoiceOver on iOS) when the barrier is focused. |
| /// See also: |
| /// |
| /// * [ModalRoute.barrierLabel], which controls this property for the |
| /// [ModalBarrier] built by [ModalRoute] pages. |
| final String semanticsLabel; |
| |
| @override |
| Widget build(BuildContext context) { |
| return new ModalBarrier( |
| color: color?.value, |
| dismissible: dismissible, |
| semanticsLabel: semanticsLabel, |
| ); |
| } |
| } |