Commit e8c9797d authored by Ian Hickson's avatar Ian Hickson Committed by GitHub
parent 8e64624a
......@@ -68,6 +68,19 @@ class ChangeNotifier extends Listenable {
/// If the given listener is not registered, the call is ignored.
///
/// This method must not be called after [dispose] has been called.
///
/// If a listener had been added twice, and is removed once during an
/// iteration (i.e. in response to a notification), it will still be called
/// again. If, on the other hand, it is removed as many times as it was
/// registered, then it will no longer be called. This odd behavior is the
/// result of the [ChangeNotifier] not being able to determine which listener
/// is being removed, since they are identical, and therefore conservatively
/// still calling all the listeners when it knows that any are still
/// registered.
///
/// This surprising behavior can be unexpectedly observed when registering a
/// listener on two separate objects which are both forwarding all
/// registrations to a common upstream object.
@override
void removeListener(VoidCallback listener) {
assert(_debugAssertNotDisposed);
......@@ -97,6 +110,10 @@ class ChangeNotifier extends Listenable {
/// [FlutterError.reportError].
///
/// This method must not be called after [dispose] has been called.
///
/// Surprising behavior can result when reentrantly removing a listener (i.e.
/// in response to a notification) that has been registered multiple times.
/// See the discussion at [removeListener].
@protected
void notifyListeners() {
assert(_debugAssertNotDisposed);
......
......@@ -21,6 +21,11 @@ import 'theme.dart';
/// corners. Avoid using flat buttons where they would blend in with other
/// content, for example in the middle of lists.
///
/// Material design flat buttons have an all-caps label, some internal padding,
/// and some defined dimensions. To have a part of your application be
/// interactive, with ink splashes, without also committing to these stylistic
/// choices, consider using [InkWell] instead.
///
/// If the [onPressed] callback is null, then the button will be disabled,
/// will not react to touch, and will be colored as specified by
/// the [disabledColor] property instead of the [color] property. If you are
......@@ -35,6 +40,7 @@ import 'theme.dart';
/// material.
/// * [DropdownButton], which offers the user a choice of a number of options.
/// * [SimpleDialogOption], which is used in [SimpleDialog]s.
/// * [InkWell], which implements the ink splash part of a flat button.
/// * <https://material.google.com/components/buttons.html>
class FlatButton extends StatelessWidget {
/// Creates a flat button.
......
......@@ -21,6 +21,11 @@ import 'theme.dart';
/// is true then the overall height of this list item and the size of the
/// [DefaultTextStyle]s that wrap the [title] and [subtitle] widget are reduced.
///
/// List items are always a fixed height (which height depends on how
/// [isThreeLine], [dense], and [subtitle] are configured); they do not grow in
/// height based on their contents. If you are looking for a widget that allows
/// for arbitrary layout in a row, consider [Row].
///
/// List items are typically used in [MaterialList]s or in [Card]s.
///
/// Requires one of its ancestors to be a [Material] widget.
......@@ -84,7 +89,7 @@ class ListItem extends StatelessWidget {
/// Whether this list item is interactive.
///
/// If `false`, this list item is styled with the disabled color from the
/// If false, this list item is styled with the disabled color from the
/// current [Theme] and the [onTap] and [onLongPress] callbacks are
/// inoperative.
final bool enabled;
......
......@@ -59,7 +59,7 @@ class TwoLevelListItem extends StatelessWidget {
/// Whether this list item is interactive.
///
/// If `false`, this list item is styled with the disabled color from the
/// If false, this list item is styled with the disabled color from the
/// current [Theme] and the [onTap] and [onLongPress] callbacks are
/// inoperative.
final bool enabled;
......@@ -128,7 +128,7 @@ class TwoLevelSublist extends StatefulWidget {
///
/// When the sublist starts expanding, this function is called with the value
/// `true`. When the sublist starts collapsing, this function is called with
/// the value `false`.
/// the value false.
final ValueChanged<bool> onOpenChanged;
/// The widgets that are displayed when the sublist expands.
......
......@@ -540,7 +540,7 @@ class RenderGrid extends RenderVirtualViewport<GridParentData> {
///
/// If the new delegate is the same class as the previous one, then the new
/// delegate has its [GridDelegate.shouldRelayout] called; if the result is
/// `true`, then the delegate will be called.
/// true, then the delegate will be called.
///
/// If the new delegate is a different class than the previous one, then the
/// delegate will be called.
......
......@@ -55,7 +55,7 @@ enum PerformanceOverlayOption {
///
/// The simplest way to show the performance overlay is to set
/// [MaterialApp.showPerformanceOverlay] or [WidgetsApp.showPerformanceOverlay]
/// to `true`.
/// to true.
class RenderPerformanceOverlay extends RenderBox {
/// Creates a performance overlay render object.
///
......
......@@ -909,15 +909,15 @@ abstract class CustomClipper<T> {
/// the same thing, because the latter is implemented in terms of the former).
///
/// If the new instance represents different information than the old
/// instance, then the method should return `true`, otherwise it should return
/// `false`.
/// instance, then the method should return true, otherwise it should return
/// false.
///
/// If the method returns `false`, then the [getClip] call might be optimized
/// If the method returns false, then the [getClip] call might be optimized
/// away.
///
/// It's possible that the [getClip] method will get called even if
/// [shouldReclip] returns `false` or if the [getClip] method is never called
/// at all (e.g. if the box changes size).
/// [shouldReclip] returns false or if the [shouldReclip] method is never
/// called at all (e.g. if the box changes size).
bool shouldReclip(@checked CustomClipper<T> oldClipper);
}
......@@ -1361,8 +1361,8 @@ class RenderTransform extends RenderProxyBox {
markNeedsPaint();
}
/// When set to `true`, hit tests are performed based on the position of the
/// child as it is painted. When set to `false`, hit tests are performed
/// When set to true, hit tests are performed based on the position of the
/// child as it is painted. When set to false, hit tests are performed
/// ignoring the transformation.
///
/// applyPaintTransform(), and therefore localToGlobal() and globalToLocal(),
......@@ -1643,8 +1643,8 @@ class RenderFractionalTranslation extends RenderProxyBox {
markNeedsPaint();
}
/// When set to `true`, hit tests are performed based on the position of the
/// child as it is painted. When set to `false`, hit tests are performed
/// When set to true, hit tests are performed based on the position of the
/// child as it is painted. When set to false, hit tests are performed
/// ignoring the transformation.
///
/// applyPaintTransform(), and therefore localToGlobal() and globalToLocal(),
......@@ -1745,14 +1745,14 @@ abstract class CustomPainter {
/// implemented in terms of the former).
///
/// If the new instance represents different information than the old
/// instance, then the method should return `true`, otherwise it should return
/// `false`.
/// instance, then the method should return true, otherwise it should return
/// false.
///
/// If the method returns `false`, then the [paint] call might be optimized
/// If the method returns false, then the [paint] call might be optimized
/// away.
///
/// It's possible that the [paint] method will get called even if
/// [shouldRepaint] returns `false` (e.g. if an ancestor or descendant needed to
/// [shouldRepaint] returns false (e.g. if an ancestor or descendant needed to
/// be repainted). It's also possible that the [paint] method will get called
/// without [shouldRepaint] being called at all (e.g. if the box changes
/// size).
......@@ -1760,7 +1760,7 @@ abstract class CustomPainter {
/// If a custom delegate has a particularly expensive paint function such that
/// repaints should be avoided as much as possible, a [RepaintBoundary] or
/// [RenderRepaintBoundary] (or other render object with [isRepaintBoundary]
/// set to `true`) might be helpful.
/// set to true) might be helpful.
bool shouldRepaint(@checked CustomPainter oldDelegate);
/// Called whenever a hit test is being performed on an object that is using
......@@ -1772,8 +1772,8 @@ abstract class CustomPainter {
/// The default behavior is to consider all points to be hits for
/// background painters, and no points to be hits for foreground painters.
///
/// Return `true` if the given position corresponds to a point on the drawn
/// image that should be considered a "hit", `false` if it corresponds to a
/// Return true if the given position corresponds to a point on the drawn
/// image that should be considered a "hit", false if it corresponds to a
/// point that should be considered outside the painted image, and null to use
/// the default behavior.
bool hitTest(Point position) => null;
......@@ -1829,7 +1829,7 @@ class RenderCustomPaint extends RenderProxyBox {
///
/// If the new delegate is the same class as the previous one, then the new
/// delegate has its [CustomPainter.shouldRepaint] called; if the result is
/// `true`, then the delegate will be called.
/// true, then the delegate will be called.
///
/// If the new delegate is a different class than the previous one, then the
/// delegate will be called.
......@@ -1854,7 +1854,7 @@ class RenderCustomPaint extends RenderProxyBox {
///
/// If the new delegate is the same class as the previous one, then the new
/// delegate has its [CustomPainter.shouldRepaint] called; if the result is
/// `true`, then the delegate will be called.
/// true, then the delegate will be called.
///
/// If the new delegate is a different class than the previous one, then the
/// delegate will be called.
......@@ -2192,12 +2192,12 @@ class RenderRepaintBoundary extends RenderProxyBox {
/// A render object that is invisible during hit testing.
///
/// When [ignoring] is `true`, this render object (and its subtree) is invisible
/// When [ignoring] is true, this render object (and its subtree) is invisible
/// to hit testing. It still consumes space during layout and paints its child
/// as usual. It just cannot be the target of located events, because its render
/// object returns `false` from [hitTest].
/// object returns false from [hitTest].
///
/// When [ignoringSemantics] is `true`, the subtree will be invisible to
/// When [ignoringSemantics] is true, the subtree will be invisible to
/// the semantics layer (and thus e.g. accessibility tools). If
/// [ignoringSemantics] is null, it uses the value of [ignoring].
class RenderIgnorePointer extends RenderProxyBox {
......@@ -2378,11 +2378,11 @@ class RenderOffstage extends RenderProxyBox {
/// A render object that absorbs pointers during hit testing.
///
/// When [absorbing] is `true`, this render object prevents its subtree from
/// When [absorbing] is true, this render object prevents its subtree from
/// receiving pointer events by terminating hit testing at itself. It still
/// consumes space during layout and paints its child as usual. It just prevents
/// its children from being the target of located events, because its render
/// object returns `true` from [hitTest].
/// object returns true from [hitTest].
class RenderAbsorbPointer extends RenderProxyBox {
/// Creates a render object that absorbs pointers during hit testing.
///
......@@ -2611,11 +2611,11 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
assert(container != null);
}
/// If 'container' is `true`, this RenderObject will introduce a new
/// If 'container' is true, this RenderObject will introduce a new
/// node in the semantics tree. Otherwise, the semantics will be
/// merged with the semantics of any ancestors.
///
/// The 'container' flag is implicitly set to `true` on the immediate
/// The 'container' flag is implicitly set to true on the immediate
/// semantics-providing descendants of a node where multiple
/// children have semantics or have descendants providing semantics.
/// In other words, the semantics of siblings are not merged. To
......@@ -2631,7 +2631,7 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
markNeedsSemanticsUpdate();
}
/// If non-null, sets the "hasCheckedState" semantic to `true` and the
/// If non-null, sets the "hasCheckedState" semantic to true and the
/// "isChecked" semantic to the given value.
bool get checked => _checked;
bool _checked;
......
......@@ -289,7 +289,8 @@ class SemanticsNode extends AbstractNode {
bool get hasCheckedState => (_flags & SemanticsFlags.hasCheckedState.index) != 0;
set hasCheckedState(bool value) => _setFlag(SemanticsFlags.hasCheckedState, value);
/// If this node has Boolean state that can be controlled by the user, whether that state is on or off, corresponding to `true` and `false`, respectively.
/// If this node has Boolean state that can be controlled by the user, whether
/// that state is on or off, corresponding to true and false, respectively.
bool get isChecked => (_flags & SemanticsFlags.isChecked.index) != 0;
set isChecked(bool value) => _setFlag(SemanticsFlags.isChecked, value);
......
......@@ -736,15 +736,15 @@ abstract class SingleChildLayoutDelegate {
/// because the latter is implemented in terms of the former).
///
/// If the new instance represents different information than the old
/// instance, then the method should return `true`, otherwise it should return
/// `false`.
/// instance, then the method should return true, otherwise it should return
/// false.
///
/// If the method returns `false`, then the [getSize],
/// If the method returns false, then the [getSize],
/// [getConstraintsForChild], and [getPositionForChild] calls might be
/// optimized away.
///
/// It's possible that the layout methods will get called even if
/// [shouldRelayout] returns `false` (e.g. if an ancestor changed its layout).
/// [shouldRelayout] returns false (e.g. if an ancestor changed its layout).
/// It's also possible that the layout method will get called
/// without [shouldRelayout] being called at all (e.g. if the parent changes
/// size).
......
......@@ -54,10 +54,10 @@ abstract class AssetBundle {
/// Retrieve a string from the asset bundle.
///
/// If the `cache` argument is set to `false`, then the data will not be
/// If the `cache` argument is set to false, then the data will not be
/// cached, and reading the data may bypass the cache. This is useful if the
/// caller is going to be doing its own caching. (It might not be cached if
/// it's set to `true` either, that depends on the asset bundle
/// it's set to true either, that depends on the asset bundle
/// implementation.)
Future<String> loadString(String key, { bool cache: true });
......
......@@ -2872,12 +2872,12 @@ class RepaintBoundary extends SingleChildRenderObjectWidget {
/// A widget that is invisible during hit testing.
///
/// When [ignoring] is `true`, this widget (and its subtree) is invisible
/// When [ignoring] is true, this widget (and its subtree) is invisible
/// to hit testing. It still consumes space during layout and paints its child
/// as usual. It just cannot be the target of located events, because it returns
/// `false` from [hitTest].
/// false from [hitTest].
///
/// When [ignoringSemantics] is `true`, the subtree will be invisible to
/// When [ignoringSemantics] is true, the subtree will be invisible to
/// the semantics layer (and thus e.g. accessibility tools). If
/// [ignoringSemantics] is null, it uses the value of [ignoring].
///
......@@ -2936,10 +2936,10 @@ class IgnorePointer extends SingleChildRenderObjectWidget {
/// A widget that absorbs pointers during hit testing.
///
/// When [absorbing] is `true`, this widget prevents its subtree from receiving
/// When [absorbing] is true, this widget prevents its subtree from receiving
/// pointer events by terminating hit testing at itself. It still consumes space
/// during layout and paints its child as usual. It just prevents its children
/// from being the target of located events, because it returns `true` from
/// from being the target of located events, because it returns true from
/// [hitTest].
///
/// See also:
......
......@@ -347,7 +347,7 @@ class TypeMatcher<T> {
/// Creates a type matcher for the given type parameter.
const TypeMatcher();
/// Returns `true` if the given object is of type `T`.
/// Returns true if the given object is of type `T`.
bool check(dynamic object) => object is T;
}
......@@ -397,6 +397,13 @@ abstract class Widget {
/// new widget). Otherwise, the old element is removed from the tree, the new
/// widget is inflated into an element, and the new element is inserted into the
/// tree.
///
/// Using a [GlobalKey] as the widget's [key] allows the element to be moved
/// around the tree (changing parent) without losing state. When a new widget
/// is found (its key and type do not match a previous widget in the same
/// location), but there was a widget with that same global key elsewhere in
/// the tree in the previous frame, then that widget's element is moved to the
/// new location.
final Key key;
/// Inflates this configuration to a concrete instance.
......@@ -443,6 +450,10 @@ abstract class Widget {
/// An element that uses a given widget as its configuration can be updated to
/// use another widget as its configuration if, and only if, the two widgets
/// have [runtimeType] and [key] properties that are [operator==].
///
/// If the widgets have no key (their key is null), then they are considered a
/// match if they have the same type, even if their children are completely
/// different.
static bool canUpdate(Widget oldWidget, Widget newWidget) {
return oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key;
......
......@@ -981,7 +981,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
///
/// The given `route` must have already received a call to [Route.didPop].
/// This function may be called directly from [Route.didPop] if [Route.didPop]
/// will return `true`.
/// will return true.
void finalizeRoute(Route<dynamic> route) {
_poppedRoutes.remove(route);
route.dispose();
......
......@@ -19,7 +19,7 @@ import 'framework.dart';
///
/// The simplest way to show the performance overlay is to set
/// [MaterialApp.showPerformanceOverlay] or [WidgetsApp.showPerformanceOverlay]
/// to `true`.
/// to true.
class PerformanceOverlay extends LeafRenderObjectWidget {
// TODO(abarth): We should have a page on the web site with a screenshot and
// an explanation of all the various readouts.
......
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