Unverified Commit 2aa348b9 authored by Pierre-Louis's avatar Pierre-Louis Committed by GitHub

Use `curly_braces_in_flow_control_structures` for `widgets` (#104609)

* Use `curly_braces_in_flow_control_structures` for `widgets`

* fix comments

* fix comments
parent f22c2033
...@@ -1503,8 +1503,9 @@ class PrioritizedAction extends Action<PrioritizedIntents> { ...@@ -1503,8 +1503,9 @@ class PrioritizedAction extends Action<PrioritizedIntents> {
@override @override
bool isEnabled(PrioritizedIntents intent) { bool isEnabled(PrioritizedIntents intent) {
final FocusNode? focus = primaryFocus; final FocusNode? focus = primaryFocus;
if (focus == null || focus.context == null) if (focus == null || focus.context == null) {
return false; return false;
}
for (final Intent candidateIntent in intent.orderedIntents) { for (final Intent candidateIntent in intent.orderedIntents) {
final Action<Intent>? candidateAction = Actions.maybeFind<Intent>( final Action<Intent>? candidateAction = Actions.maybeFind<Intent>(
focus.context!, focus.context!,
......
...@@ -269,8 +269,9 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid ...@@ -269,8 +269,9 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid
reverseDuration: widget.reverseDuration, reverseDuration: widget.reverseDuration,
vsync: this, vsync: this,
); );
if (widget.crossFadeState == CrossFadeState.showSecond) if (widget.crossFadeState == CrossFadeState.showSecond) {
_controller.value = 1.0; _controller.value = 1.0;
}
_firstAnimation = _initAnimation(widget.firstCurve, true); _firstAnimation = _initAnimation(widget.firstCurve, true);
_secondAnimation = _initAnimation(widget.secondCurve, false); _secondAnimation = _initAnimation(widget.secondCurve, false);
_controller.addStatusListener((AnimationStatus status) { _controller.addStatusListener((AnimationStatus status) {
...@@ -283,8 +284,9 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid ...@@ -283,8 +284,9 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid
Animation<double> _initAnimation(Curve curve, bool inverted) { Animation<double> _initAnimation(Curve curve, bool inverted) {
Animation<double> result = _controller.drive(CurveTween(curve: curve)); Animation<double> result = _controller.drive(CurveTween(curve: curve));
if (inverted) if (inverted) {
result = result.drive(Tween<double>(begin: 1.0, end: 0.0)); result = result.drive(Tween<double>(begin: 1.0, end: 0.0));
}
return result; return result;
} }
...@@ -297,14 +299,18 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid ...@@ -297,14 +299,18 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid
@override @override
void didUpdateWidget(AnimatedCrossFade oldWidget) { void didUpdateWidget(AnimatedCrossFade oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
if (widget.duration != oldWidget.duration) if (widget.duration != oldWidget.duration) {
_controller.duration = widget.duration; _controller.duration = widget.duration;
if (widget.reverseDuration != oldWidget.reverseDuration) }
if (widget.reverseDuration != oldWidget.reverseDuration) {
_controller.reverseDuration = widget.reverseDuration; _controller.reverseDuration = widget.reverseDuration;
if (widget.firstCurve != oldWidget.firstCurve) }
if (widget.firstCurve != oldWidget.firstCurve) {
_firstAnimation = _initAnimation(widget.firstCurve, true); _firstAnimation = _initAnimation(widget.firstCurve, true);
if (widget.secondCurve != oldWidget.secondCurve) }
if (widget.secondCurve != oldWidget.secondCurve) {
_secondAnimation = _initAnimation(widget.secondCurve, false); _secondAnimation = _initAnimation(widget.secondCurve, false);
}
if (widget.crossFadeState != oldWidget.crossFadeState) { if (widget.crossFadeState != oldWidget.crossFadeState) {
switch (widget.crossFadeState) { switch (widget.crossFadeState) {
case CrossFadeState.showFirst: case CrossFadeState.showFirst:
......
...@@ -488,11 +488,12 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi ...@@ -488,11 +488,12 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi
int _indexToItemIndex(int index) { int _indexToItemIndex(int index) {
int itemIndex = index; int itemIndex = index;
for (final _ActiveItem item in _outgoingItems) { for (final _ActiveItem item in _outgoingItems) {
if (item.itemIndex <= itemIndex) if (item.itemIndex <= itemIndex) {
itemIndex += 1; itemIndex += 1;
else } else {
break; break;
} }
}
return itemIndex; return itemIndex;
} }
...@@ -500,11 +501,12 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi ...@@ -500,11 +501,12 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi
int index = itemIndex; int index = itemIndex;
for (final _ActiveItem item in _outgoingItems) { for (final _ActiveItem item in _outgoingItems) {
assert(item.itemIndex != itemIndex); assert(item.itemIndex != itemIndex);
if (item.itemIndex < itemIndex) if (item.itemIndex < itemIndex) {
index -= 1; index -= 1;
else } else {
break; break;
} }
}
return index; return index;
} }
...@@ -532,13 +534,15 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi ...@@ -532,13 +534,15 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi
// Increment the incoming and outgoing item indices to account // Increment the incoming and outgoing item indices to account
// for the insertion. // for the insertion.
for (final _ActiveItem item in _incomingItems) { for (final _ActiveItem item in _incomingItems) {
if (item.itemIndex >= itemIndex) if (item.itemIndex >= itemIndex) {
item.itemIndex += 1; item.itemIndex += 1;
} }
}
for (final _ActiveItem item in _outgoingItems) { for (final _ActiveItem item in _outgoingItems) {
if (item.itemIndex >= itemIndex) if (item.itemIndex >= itemIndex) {
item.itemIndex += 1; item.itemIndex += 1;
} }
}
final AnimationController controller = AnimationController( final AnimationController controller = AnimationController(
duration: duration, duration: duration,
...@@ -596,13 +600,15 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi ...@@ -596,13 +600,15 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi
// Decrement the incoming and outgoing item indices to account // Decrement the incoming and outgoing item indices to account
// for the removal. // for the removal.
for (final _ActiveItem item in _incomingItems) { for (final _ActiveItem item in _incomingItems) {
if (item.itemIndex > outgoingItem.itemIndex) if (item.itemIndex > outgoingItem.itemIndex) {
item.itemIndex -= 1; item.itemIndex -= 1;
} }
}
for (final _ActiveItem item in _outgoingItems) { for (final _ActiveItem item in _outgoingItems) {
if (item.itemIndex > outgoingItem.itemIndex) if (item.itemIndex > outgoingItem.itemIndex) {
item.itemIndex -= 1; item.itemIndex -= 1;
} }
}
setState(() => _itemsCount -= 1); setState(() => _itemsCount -= 1);
}); });
......
...@@ -272,8 +272,9 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider ...@@ -272,8 +272,9 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider
// transitions. // transitions.
if (widget.transitionBuilder != oldWidget.transitionBuilder) { if (widget.transitionBuilder != oldWidget.transitionBuilder) {
_outgoingEntries.forEach(_updateTransitionForEntry); _outgoingEntries.forEach(_updateTransitionForEntry);
if (_currentEntry != null) if (_currentEntry != null) {
_updateTransitionForEntry(_currentEntry!); _updateTransitionForEntry(_currentEntry!);
}
_markChildWidgetCacheAsDirty(); _markChildWidgetCacheAsDirty();
} }
...@@ -307,8 +308,9 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider ...@@ -307,8 +308,9 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider
_markChildWidgetCacheAsDirty(); _markChildWidgetCacheAsDirty();
_currentEntry = null; _currentEntry = null;
} }
if (widget.child == null) if (widget.child == null) {
return; return;
}
final AnimationController controller = AnimationController( final AnimationController controller = AnimationController(
duration: widget.duration, duration: widget.duration,
reverseDuration: widget.reverseDuration, reverseDuration: widget.reverseDuration,
...@@ -380,10 +382,12 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider ...@@ -380,10 +382,12 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider
@override @override
void dispose() { void dispose() {
if (_currentEntry != null) if (_currentEntry != null) {
_currentEntry!.controller.dispose(); _currentEntry!.controller.dispose();
for (final _ChildEntry entry in _outgoingEntries) }
for (final _ChildEntry entry in _outgoingEntries) {
entry.controller.dispose(); entry.controller.dispose();
}
super.dispose(); super.dispose();
} }
......
...@@ -1409,8 +1409,9 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver { ...@@ -1409,8 +1409,9 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
assert(route != null, 'The pageRouteBuilder for WidgetsApp must return a valid non-null Route.'); assert(route != null, 'The pageRouteBuilder for WidgetsApp must return a valid non-null Route.');
return route; return route;
} }
if (widget.onGenerateRoute != null) if (widget.onGenerateRoute != null) {
return widget.onGenerateRoute!(settings); return widget.onGenerateRoute!(settings);
}
return null; return null;
} }
...@@ -1454,12 +1455,14 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver { ...@@ -1454,12 +1455,14 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
assert(mounted); assert(mounted);
// The back button dispatcher should handle the pop route if we use a // The back button dispatcher should handle the pop route if we use a
// router. // router.
if (_usesRouterWithDelegates) if (_usesRouterWithDelegates) {
return false; return false;
}
final NavigatorState? navigator = _navigator?.currentState; final NavigatorState? navigator = _navigator?.currentState;
if (navigator == null) if (navigator == null) {
return false; return false;
}
return navigator.maybePop(); return navigator.maybePop();
} }
...@@ -1468,12 +1471,14 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver { ...@@ -1468,12 +1471,14 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
assert(mounted); assert(mounted);
// The route name provider should handle the push route if we uses a // The route name provider should handle the push route if we uses a
// router. // router.
if (_usesRouterWithDelegates) if (_usesRouterWithDelegates) {
return false; return false;
}
final NavigatorState? navigator = _navigator?.currentState; final NavigatorState? navigator = _navigator?.currentState;
if (navigator == null) if (navigator == null) {
return false; return false;
}
navigator.pushNamed(route); navigator.pushNamed(route);
return true; return true;
} }
...@@ -1487,18 +1492,20 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver { ...@@ -1487,18 +1492,20 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
// Attempt to use localeListResolutionCallback. // Attempt to use localeListResolutionCallback.
if (widget.localeListResolutionCallback != null) { if (widget.localeListResolutionCallback != null) {
final Locale? locale = widget.localeListResolutionCallback!(preferredLocales, widget.supportedLocales); final Locale? locale = widget.localeListResolutionCallback!(preferredLocales, widget.supportedLocales);
if (locale != null) if (locale != null) {
return locale; return locale;
} }
}
// localeListResolutionCallback failed, falling back to localeResolutionCallback. // localeListResolutionCallback failed, falling back to localeResolutionCallback.
if (widget.localeResolutionCallback != null) { if (widget.localeResolutionCallback != null) {
final Locale? locale = widget.localeResolutionCallback!( final Locale? locale = widget.localeResolutionCallback!(
preferredLocales != null && preferredLocales.isNotEmpty ? preferredLocales.first : null, preferredLocales != null && preferredLocales.isNotEmpty ? preferredLocales.first : null,
widget.supportedLocales, widget.supportedLocales,
); );
if (locale != null) if (locale != null) {
return locale; return locale;
} }
}
// Both callbacks failed, falling back to default algorithm. // Both callbacks failed, falling back to default algorithm.
return basicLocaleListResolution(preferredLocales, supportedLocales); return basicLocaleListResolution(preferredLocales, supportedLocales);
} }
...@@ -1533,13 +1540,16 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver { ...@@ -1533,13 +1540,16 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
final Set<Type> unsupportedTypes = final Set<Type> unsupportedTypes =
_localizationsDelegates.map<Type>((LocalizationsDelegate<dynamic> delegate) => delegate.type).toSet(); _localizationsDelegates.map<Type>((LocalizationsDelegate<dynamic> delegate) => delegate.type).toSet();
for (final LocalizationsDelegate<dynamic> delegate in _localizationsDelegates) { for (final LocalizationsDelegate<dynamic> delegate in _localizationsDelegates) {
if (!unsupportedTypes.contains(delegate.type)) if (!unsupportedTypes.contains(delegate.type)) {
continue; continue;
if (delegate.isSupported(appLocale)) }
if (delegate.isSupported(appLocale)) {
unsupportedTypes.remove(delegate.type); unsupportedTypes.remove(delegate.type);
} }
if (unsupportedTypes.isEmpty) }
if (unsupportedTypes.isEmpty) {
return true; return true;
}
FlutterError.reportError(FlutterErrorDetails( FlutterError.reportError(FlutterErrorDetails(
exception: "Warning: This application's locale, $appLocale, is not supported by all of its localization delegates.", exception: "Warning: This application's locale, $appLocale, is not supported by all of its localization delegates.",
......
...@@ -246,10 +246,12 @@ class AsyncSnapshot<T> { ...@@ -246,10 +246,12 @@ class AsyncSnapshot<T> {
/// Throws [error], if [hasError]. Throws [StateError], if neither [hasData] /// Throws [error], if [hasError]. Throws [StateError], if neither [hasData]
/// nor [hasError]. /// nor [hasError].
T get requireData { T get requireData {
if (hasData) if (hasData) {
return data!; return data!;
if (hasError) }
if (hasError) {
Error.throwWithStackTrace(error!, stackTrace!); Error.throwWithStackTrace(error!, stackTrace!);
}
throw StateError('Snapshot has neither data nor error'); throw StateError('Snapshot has neither data nor error');
} }
...@@ -294,8 +296,9 @@ class AsyncSnapshot<T> { ...@@ -294,8 +296,9 @@ class AsyncSnapshot<T> {
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
if (identical(this, other)) if (identical(this, other)) {
return true; return true;
}
return other is AsyncSnapshot<T> return other is AsyncSnapshot<T>
&& other.connectionState == connectionState && other.connectionState == connectionState
&& other.data == data && other.data == data
......
...@@ -186,8 +186,9 @@ class AutofillGroupState extends State<AutofillGroup> with AutofillScopeMixin { ...@@ -186,8 +186,9 @@ class AutofillGroupState extends State<AutofillGroup> with AutofillScopeMixin {
void dispose() { void dispose() {
super.dispose(); super.dispose();
if (!_isTopmostAutofillGroup || widget.onDisposeAction == null) if (!_isTopmostAutofillGroup || widget.onDisposeAction == null) {
return; return;
}
switch (widget.onDisposeAction) { switch (widget.onDisposeAction) {
case AutofillContextAction.cancel: case AutofillContextAction.cancel:
TextInput.finishAutofillContext(shouldSave: false); TextInput.finishAutofillContext(shouldSave: false);
......
...@@ -69,9 +69,10 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> { ...@@ -69,9 +69,10 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
@override @override
void dispose() { void dispose() {
if (_handles != null) { if (_handles != null) {
for (final Listenable handle in _handles!.keys) for (final Listenable handle in _handles!.keys) {
handle.removeListener(_handles![handle]!); handle.removeListener(_handles![handle]!);
} }
}
super.dispose(); super.dispose();
} }
...@@ -368,33 +369,38 @@ mixin AutomaticKeepAliveClientMixin<T extends StatefulWidget> on State<T> { ...@@ -368,33 +369,38 @@ mixin AutomaticKeepAliveClientMixin<T extends StatefulWidget> on State<T> {
@protected @protected
void updateKeepAlive() { void updateKeepAlive() {
if (wantKeepAlive) { if (wantKeepAlive) {
if (_keepAliveHandle == null) if (_keepAliveHandle == null) {
_ensureKeepAlive(); _ensureKeepAlive();
}
} else { } else {
if (_keepAliveHandle != null) if (_keepAliveHandle != null) {
_releaseKeepAlive(); _releaseKeepAlive();
} }
} }
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
if (wantKeepAlive) if (wantKeepAlive) {
_ensureKeepAlive(); _ensureKeepAlive();
} }
}
@override @override
void deactivate() { void deactivate() {
if (_keepAliveHandle != null) if (_keepAliveHandle != null) {
_releaseKeepAlive(); _releaseKeepAlive();
}
super.deactivate(); super.deactivate();
} }
@mustCallSuper @mustCallSuper
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (wantKeepAlive && _keepAliveHandle == null) if (wantKeepAlive && _keepAliveHandle == null) {
_ensureKeepAlive(); _ensureKeepAlive();
}
return const _NullWidget(); return const _NullWidget();
} }
} }
......
...@@ -135,8 +135,9 @@ class BannerPainter extends CustomPainter { ...@@ -135,8 +135,9 @@ class BannerPainter extends CustomPainter {
@override @override
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
if (!_prepared) if (!_prepared) {
_prepare(); _prepare();
}
canvas canvas
..translate(_translationX(size.width), _translationY(size.height)) ..translate(_translationX(size.width), _translationY(size.height))
..rotate(_rotation) ..rotate(_rotation)
......
...@@ -2170,10 +2170,11 @@ class LayoutId extends ParentDataWidget<MultiChildLayoutParentData> { ...@@ -2170,10 +2170,11 @@ class LayoutId extends ParentDataWidget<MultiChildLayoutParentData> {
if (parentData.id != id) { if (parentData.id != id) {
parentData.id = id; parentData.id = id;
final AbstractNode? targetParent = renderObject.parent; final AbstractNode? targetParent = renderObject.parent;
if (targetParent is RenderObject) if (targetParent is RenderObject) {
targetParent.markNeedsLayout(); targetParent.markNeedsLayout();
} }
} }
}
@override @override
Type get debugTypicalAncestorWidgetClass => CustomMultiChildLayout; Type get debugTypicalAncestorWidgetClass => CustomMultiChildLayout;
...@@ -3175,9 +3176,10 @@ class _OffstageElement extends SingleChildRenderObjectElement { ...@@ -3175,9 +3176,10 @@ class _OffstageElement extends SingleChildRenderObjectElement {
@override @override
void debugVisitOnstageChildren(ElementVisitor visitor) { void debugVisitOnstageChildren(ElementVisitor visitor) {
if (!(widget as Offstage).offstage) if (!(widget as Offstage).offstage) {
super.debugVisitOnstageChildren(visitor); super.debugVisitOnstageChildren(visitor);
} }
}
} }
/// A widget that attempts to size the child to a specific aspect ratio. /// A widget that attempts to size the child to a specific aspect ratio.
...@@ -4133,10 +4135,11 @@ class Positioned extends ParentDataWidget<StackParentData> { ...@@ -4133,10 +4135,11 @@ class Positioned extends ParentDataWidget<StackParentData> {
if (needsLayout) { if (needsLayout) {
final AbstractNode? targetParent = renderObject.parent; final AbstractNode? targetParent = renderObject.parent;
if (targetParent is RenderObject) if (targetParent is RenderObject) {
targetParent.markNeedsLayout(); targetParent.markNeedsLayout();
} }
} }
}
@override @override
Type get debugTypicalAncestorWidgetClass => Stack; Type get debugTypicalAncestorWidgetClass => Stack;
...@@ -4993,10 +4996,11 @@ class Flexible extends ParentDataWidget<FlexParentData> { ...@@ -4993,10 +4996,11 @@ class Flexible extends ParentDataWidget<FlexParentData> {
if (needsLayout) { if (needsLayout) {
final AbstractNode? targetParent = renderObject.parent; final AbstractNode? targetParent = renderObject.parent;
if (targetParent is RenderObject) if (targetParent is RenderObject) {
targetParent.markNeedsLayout(); targetParent.markNeedsLayout();
} }
} }
}
@override @override
Type get debugTypicalAncestorWidgetClass => Flex; Type get debugTypicalAncestorWidgetClass => Flex;
...@@ -6437,12 +6441,15 @@ class MouseRegion extends SingleChildRenderObjectWidget { ...@@ -6437,12 +6441,15 @@ class MouseRegion extends SingleChildRenderObjectWidget {
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
final List<String> listeners = <String>[]; final List<String> listeners = <String>[];
if (onEnter != null) if (onEnter != null) {
listeners.add('enter'); listeners.add('enter');
if (onExit != null) }
if (onExit != null) {
listeners.add('exit'); listeners.add('exit');
if (onHover != null) }
if (onHover != null) {
listeners.add('hover'); listeners.add('hover');
}
properties.add(IterableProperty<String>('listeners', listeners, ifEmpty: '<none>')); properties.add(IterableProperty<String>('listeners', listeners, ifEmpty: '<none>'));
properties.add(DiagnosticsProperty<MouseCursor>('cursor', cursor, defaultValue: null)); properties.add(DiagnosticsProperty<MouseCursor>('cursor', cursor, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('opaque', opaque, defaultValue: true)); properties.add(DiagnosticsProperty<bool>('opaque', opaque, defaultValue: true));
...@@ -6957,8 +6964,9 @@ class Semantics extends SingleChildRenderObjectWidget { ...@@ -6957,8 +6964,9 @@ class Semantics extends SingleChildRenderObjectWidget {
} }
TextDirection? _getTextDirection(BuildContext context) { TextDirection? _getTextDirection(BuildContext context) {
if (properties.textDirection != null) if (properties.textDirection != null) {
return properties.textDirection; return properties.textDirection;
}
final bool containsText = properties.attributedLabel != null || final bool containsText = properties.attributedLabel != null ||
properties.label != null || properties.label != null ||
...@@ -6966,8 +6974,9 @@ class Semantics extends SingleChildRenderObjectWidget { ...@@ -6966,8 +6974,9 @@ class Semantics extends SingleChildRenderObjectWidget {
properties.hint != null || properties.hint != null ||
properties.tooltip != null; properties.tooltip != null;
if (!containsText) if (!containsText) {
return null; return null;
}
return Directionality.maybeOf(context); return Directionality.maybeOf(context);
} }
...@@ -7195,8 +7204,9 @@ class KeyedSubtree extends StatelessWidget { ...@@ -7195,8 +7204,9 @@ class KeyedSubtree extends StatelessWidget {
/// Wrap each item in a KeyedSubtree whose key is based on the item's existing key or /// Wrap each item in a KeyedSubtree whose key is based on the item's existing key or
/// the sum of its list index and `baseIndex`. /// the sum of its list index and `baseIndex`.
static List<Widget> ensureUniqueKeysForList(List<Widget> items, { int baseIndex = 0 }) { static List<Widget> ensureUniqueKeysForList(List<Widget> items, { int baseIndex = 0 }) {
if (items == null || items.isEmpty) if (items == null || items.isEmpty) {
return items; return items;
}
final List<Widget> itemsWithUniqueKeys = <Widget>[]; final List<Widget> itemsWithUniqueKeys = <Widget>[];
int itemIndex = baseIndex; int itemIndex = baseIndex;
......
...@@ -375,8 +375,9 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -375,8 +375,9 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
getter: () => getter: () =>
Future<bool>.value(WidgetsApp.showPerformanceOverlayOverride), Future<bool>.value(WidgetsApp.showPerformanceOverlayOverride),
setter: (bool value) { setter: (bool value) {
if (WidgetsApp.showPerformanceOverlayOverride == value) if (WidgetsApp.showPerformanceOverlayOverride == value) {
return Future<void>.value(); return Future<void>.value();
}
WidgetsApp.showPerformanceOverlayOverride = value; WidgetsApp.showPerformanceOverlayOverride = value;
return _forceRebuild(); return _forceRebuild();
}, },
...@@ -431,16 +432,18 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -431,16 +432,18 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
name: 'profileWidgetBuilds', name: 'profileWidgetBuilds',
getter: () async => debugProfileBuildsEnabled, getter: () async => debugProfileBuildsEnabled,
setter: (bool value) async { setter: (bool value) async {
if (debugProfileBuildsEnabled != value) if (debugProfileBuildsEnabled != value) {
debugProfileBuildsEnabled = value; debugProfileBuildsEnabled = value;
}
}, },
); );
registerBoolServiceExtension( registerBoolServiceExtension(
name: 'profileUserWidgetBuilds', name: 'profileUserWidgetBuilds',
getter: () async => debugProfileBuildsEnabledUserWidgets, getter: () async => debugProfileBuildsEnabledUserWidgets,
setter: (bool value) async { setter: (bool value) async {
if (debugProfileBuildsEnabledUserWidgets != value) if (debugProfileBuildsEnabledUserWidgets != value) {
debugProfileBuildsEnabledUserWidgets = value; debugProfileBuildsEnabledUserWidgets = value;
}
}, },
); );
} }
...@@ -450,8 +453,9 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -450,8 +453,9 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
name: 'debugAllowBanner', name: 'debugAllowBanner',
getter: () => Future<bool>.value(WidgetsApp.debugAllowBannerOverride), getter: () => Future<bool>.value(WidgetsApp.debugAllowBannerOverride),
setter: (bool value) { setter: (bool value) {
if (WidgetsApp.debugAllowBannerOverride == value) if (WidgetsApp.debugAllowBannerOverride == value) {
return Future<void>.value(); return Future<void>.value();
}
WidgetsApp.debugAllowBannerOverride = value; WidgetsApp.debugAllowBannerOverride = value;
return _forceRebuild(); return _forceRebuild();
}, },
...@@ -463,8 +467,9 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -463,8 +467,9 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
name: 'debugWidgetInspector', name: 'debugWidgetInspector',
getter: () async => WidgetsApp.debugShowWidgetInspectorOverride, getter: () async => WidgetsApp.debugShowWidgetInspectorOverride,
setter: (bool value) { setter: (bool value) {
if (WidgetsApp.debugShowWidgetInspectorOverride == value) if (WidgetsApp.debugShowWidgetInspectorOverride == value) {
return Future<void>.value(); return Future<void>.value();
}
WidgetsApp.debugShowWidgetInspectorOverride = value; WidgetsApp.debugShowWidgetInspectorOverride = value;
return _forceRebuild(); return _forceRebuild();
}, },
...@@ -541,30 +546,34 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -541,30 +546,34 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
@override @override
void handleMetricsChanged() { void handleMetricsChanged() {
super.handleMetricsChanged(); super.handleMetricsChanged();
for (final WidgetsBindingObserver observer in _observers) for (final WidgetsBindingObserver observer in _observers) {
observer.didChangeMetrics(); observer.didChangeMetrics();
} }
}
@override @override
void handleTextScaleFactorChanged() { void handleTextScaleFactorChanged() {
super.handleTextScaleFactorChanged(); super.handleTextScaleFactorChanged();
for (final WidgetsBindingObserver observer in _observers) for (final WidgetsBindingObserver observer in _observers) {
observer.didChangeTextScaleFactor(); observer.didChangeTextScaleFactor();
} }
}
@override @override
void handlePlatformBrightnessChanged() { void handlePlatformBrightnessChanged() {
super.handlePlatformBrightnessChanged(); super.handlePlatformBrightnessChanged();
for (final WidgetsBindingObserver observer in _observers) for (final WidgetsBindingObserver observer in _observers) {
observer.didChangePlatformBrightness(); observer.didChangePlatformBrightness();
} }
}
@override @override
void handleAccessibilityFeaturesChanged() { void handleAccessibilityFeaturesChanged() {
super.handleAccessibilityFeaturesChanged(); super.handleAccessibilityFeaturesChanged();
for (final WidgetsBindingObserver observer in _observers) for (final WidgetsBindingObserver observer in _observers) {
observer.didChangeAccessibilityFeatures(); observer.didChangeAccessibilityFeatures();
} }
}
/// Called when the system locale changes. /// Called when the system locale changes.
/// ///
...@@ -586,9 +595,10 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -586,9 +595,10 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
@protected @protected
@mustCallSuper @mustCallSuper
void dispatchLocalesChanged(List<Locale>? locales) { void dispatchLocalesChanged(List<Locale>? locales) {
for (final WidgetsBindingObserver observer in _observers) for (final WidgetsBindingObserver observer in _observers) {
observer.didChangeLocales(locales); observer.didChangeLocales(locales);
} }
}
/// Notify all the observers that the active set of [AccessibilityFeatures] /// Notify all the observers that the active set of [AccessibilityFeatures]
/// has changed (using [WidgetsBindingObserver.didChangeAccessibilityFeatures]), /// has changed (using [WidgetsBindingObserver.didChangeAccessibilityFeatures]),
...@@ -599,9 +609,10 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -599,9 +609,10 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
@protected @protected
@mustCallSuper @mustCallSuper
void dispatchAccessibilityFeaturesChanged() { void dispatchAccessibilityFeaturesChanged() {
for (final WidgetsBindingObserver observer in _observers) for (final WidgetsBindingObserver observer in _observers) {
observer.didChangeAccessibilityFeatures(); observer.didChangeAccessibilityFeatures();
} }
}
/// Called when the system pops the current route. /// Called when the system pops the current route.
/// ///
...@@ -620,9 +631,10 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -620,9 +631,10 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
@protected @protected
Future<void> handlePopRoute() async { Future<void> handlePopRoute() async {
for (final WidgetsBindingObserver observer in List<WidgetsBindingObserver>.of(_observers)) { for (final WidgetsBindingObserver observer in List<WidgetsBindingObserver>.of(_observers)) {
if (await observer.didPopRoute()) if (await observer.didPopRoute()) {
return; return;
} }
}
SystemNavigator.pop(); SystemNavigator.pop();
} }
...@@ -640,10 +652,11 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -640,10 +652,11 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
@mustCallSuper @mustCallSuper
Future<void> handlePushRoute(String route) async { Future<void> handlePushRoute(String route) async {
for (final WidgetsBindingObserver observer in List<WidgetsBindingObserver>.of(_observers)) { for (final WidgetsBindingObserver observer in List<WidgetsBindingObserver>.of(_observers)) {
if (await observer.didPushRoute(route)) if (await observer.didPushRoute(route)) {
return; return;
} }
} }
}
Future<void> _handlePushRouteInformation(Map<dynamic, dynamic> routeArguments) async { Future<void> _handlePushRouteInformation(Map<dynamic, dynamic> routeArguments) async {
for (final WidgetsBindingObserver observer in List<WidgetsBindingObserver>.of(_observers)) { for (final WidgetsBindingObserver observer in List<WidgetsBindingObserver>.of(_observers)) {
...@@ -654,10 +667,11 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -654,10 +667,11 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
state: routeArguments['state'] as Object?, state: routeArguments['state'] as Object?,
), ),
) )
) ) {
return; return;
} }
} }
}
Future<dynamic> _handleNavigationInvocation(MethodCall methodCall) { Future<dynamic> _handleNavigationInvocation(MethodCall methodCall) {
switch (methodCall.method) { switch (methodCall.method) {
...@@ -674,16 +688,18 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -674,16 +688,18 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
@override @override
void handleAppLifecycleStateChanged(AppLifecycleState state) { void handleAppLifecycleStateChanged(AppLifecycleState state) {
super.handleAppLifecycleStateChanged(state); super.handleAppLifecycleStateChanged(state);
for (final WidgetsBindingObserver observer in _observers) for (final WidgetsBindingObserver observer in _observers) {
observer.didChangeAppLifecycleState(state); observer.didChangeAppLifecycleState(state);
} }
}
@override @override
void handleMemoryPressure() { void handleMemoryPressure() {
super.handleMemoryPressure(); super.handleMemoryPressure();
for (final WidgetsBindingObserver observer in _observers) for (final WidgetsBindingObserver observer in _observers) {
observer.didHaveMemoryPressure(); observer.didHaveMemoryPressure();
} }
}
bool _needToReportFirstFrame = true; bool _needToReportFirstFrame = true;
...@@ -862,8 +878,9 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -862,8 +878,9 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
} }
try { try {
if (renderViewElement != null) if (renderViewElement != null) {
buildOwner!.buildScope(renderViewElement!); buildOwner!.buildScope(renderViewElement!);
}
super.drawFrame(); super.drawFrame();
buildOwner!.finalizeTree(); buildOwner!.finalizeTree();
} finally { } finally {
...@@ -1128,9 +1145,10 @@ class RenderObjectToWidgetElement<T extends RenderObject> extends RootRenderObje ...@@ -1128,9 +1145,10 @@ class RenderObjectToWidgetElement<T extends RenderObject> extends RootRenderObje
@override @override
void visitChildren(ElementVisitor visitor) { void visitChildren(ElementVisitor visitor) {
if (_child != null) if (_child != null) {
visitor(_child!); visitor(_child!);
} }
}
@override @override
void forgetChild(Element child) { void forgetChild(Element child) {
...@@ -1239,8 +1257,9 @@ class WidgetsFlutterBinding extends BindingBase with GestureBinding, SchedulerBi ...@@ -1239,8 +1257,9 @@ class WidgetsFlutterBinding extends BindingBase with GestureBinding, SchedulerBi
/// [WidgetsFlutterBinding]. See /// [WidgetsFlutterBinding]. See
/// [TestWidgetsFlutterBinding.ensureInitialized]. /// [TestWidgetsFlutterBinding.ensureInitialized].
static WidgetsBinding ensureInitialized() { static WidgetsBinding ensureInitialized() {
if (WidgetsBinding._instance == null) if (WidgetsBinding._instance == null) {
WidgetsFlutterBinding(); WidgetsFlutterBinding();
}
return WidgetsBinding.instance; return WidgetsBinding.instance;
} }
} }
...@@ -369,11 +369,13 @@ class Container extends StatelessWidget { ...@@ -369,11 +369,13 @@ class Container extends StatelessWidget {
final Clip clipBehavior; final Clip clipBehavior;
EdgeInsetsGeometry? get _paddingIncludingDecoration { EdgeInsetsGeometry? get _paddingIncludingDecoration {
if (decoration == null || decoration!.padding == null) if (decoration == null || decoration!.padding == null) {
return padding; return padding;
}
final EdgeInsetsGeometry? decorationPadding = decoration!.padding; final EdgeInsetsGeometry? decorationPadding = decoration!.padding;
if (padding == null) if (padding == null) {
return decorationPadding; return decorationPadding;
}
return padding!.add(decorationPadding!); return padding!.add(decorationPadding!);
} }
...@@ -392,11 +394,13 @@ class Container extends StatelessWidget { ...@@ -392,11 +394,13 @@ class Container extends StatelessWidget {
} }
final EdgeInsetsGeometry? effectivePadding = _paddingIncludingDecoration; final EdgeInsetsGeometry? effectivePadding = _paddingIncludingDecoration;
if (effectivePadding != null) if (effectivePadding != null) {
current = Padding(padding: effectivePadding, child: current); current = Padding(padding: effectivePadding, child: current);
}
if (color != null) if (color != null) {
current = ColoredBox(color: color!, child: current); current = ColoredBox(color: color!, child: current);
}
if (clipBehavior != Clip.none) { if (clipBehavior != Clip.none) {
assert(decoration != null); assert(decoration != null);
...@@ -410,8 +414,9 @@ class Container extends StatelessWidget { ...@@ -410,8 +414,9 @@ class Container extends StatelessWidget {
); );
} }
if (decoration != null) if (decoration != null) {
current = DecoratedBox(decoration: decoration!, child: current); current = DecoratedBox(decoration: decoration!, child: current);
}
if (foregroundDecoration != null) { if (foregroundDecoration != null) {
current = DecoratedBox( current = DecoratedBox(
...@@ -421,14 +426,17 @@ class Container extends StatelessWidget { ...@@ -421,14 +426,17 @@ class Container extends StatelessWidget {
); );
} }
if (constraints != null) if (constraints != null) {
current = ConstrainedBox(constraints: constraints!, child: current); current = ConstrainedBox(constraints: constraints!, child: current);
}
if (margin != null) if (margin != null) {
current = Padding(padding: margin!, child: current); current = Padding(padding: margin!, child: current);
}
if (transform != null) if (transform != null) {
current = Transform(transform: transform!, alignment: transformAlignment, child: current); current = Transform(transform: transform!, alignment: transformAlignment, child: current);
}
return current!; return current!;
} }
...@@ -439,10 +447,11 @@ class Container extends StatelessWidget { ...@@ -439,10 +447,11 @@ class Container extends StatelessWidget {
properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, showName: false, defaultValue: null)); properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, showName: false, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null)); properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
properties.add(DiagnosticsProperty<Clip>('clipBehavior', clipBehavior, defaultValue: Clip.none)); properties.add(DiagnosticsProperty<Clip>('clipBehavior', clipBehavior, defaultValue: Clip.none));
if (color != null) if (color != null) {
properties.add(DiagnosticsProperty<Color>('bg', color)); properties.add(DiagnosticsProperty<Color>('bg', color));
else } else {
properties.add(DiagnosticsProperty<Decoration>('bg', decoration, defaultValue: null)); properties.add(DiagnosticsProperty<Decoration>('bg', decoration, defaultValue: null));
}
properties.add(DiagnosticsProperty<Decoration>('fg', foregroundDecoration, defaultValue: null)); properties.add(DiagnosticsProperty<Decoration>('fg', foregroundDecoration, defaultValue: null));
properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: null)); properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('margin', margin, defaultValue: null)); properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('margin', margin, defaultValue: null));
......
...@@ -165,11 +165,13 @@ Key? _firstNonUniqueKey(Iterable<Widget> widgets) { ...@@ -165,11 +165,13 @@ Key? _firstNonUniqueKey(Iterable<Widget> widgets) {
final Set<Key> keySet = HashSet<Key>(); final Set<Key> keySet = HashSet<Key>();
for (final Widget widget in widgets) { for (final Widget widget in widgets) {
assert(widget != null); assert(widget != null);
if (widget.key == null) if (widget.key == null) {
continue; continue;
if (!keySet.add(widget.key!)) }
if (!keySet.add(widget.key!)) {
return widget.key; return widget.key;
} }
}
return null; return null;
} }
...@@ -217,8 +219,9 @@ bool debugChildrenHaveDuplicateKeys(Widget parent, Iterable<Widget> children) { ...@@ -217,8 +219,9 @@ bool debugChildrenHaveDuplicateKeys(Widget parent, Iterable<Widget> children) {
bool debugItemsHaveDuplicateKeys(Iterable<Widget> items) { bool debugItemsHaveDuplicateKeys(Iterable<Widget> items) {
assert(() { assert(() {
final Key? nonUniqueKey = _firstNonUniqueKey(items); final Key? nonUniqueKey = _firstNonUniqueKey(items);
if (nonUniqueKey != null) if (nonUniqueKey != null) {
throw FlutterError('Duplicate key found: $nonUniqueKey.'); throw FlutterError('Duplicate key found: $nonUniqueKey.');
}
return true; return true;
}()); }());
return false; return false;
......
...@@ -276,13 +276,15 @@ class _DismissibleClipper extends CustomClipper<Rect> { ...@@ -276,13 +276,15 @@ class _DismissibleClipper extends CustomClipper<Rect> {
switch (axis) { switch (axis) {
case Axis.horizontal: case Axis.horizontal:
final double offset = moveAnimation.value.dx * size.width; final double offset = moveAnimation.value.dx * size.width;
if (offset < 0) if (offset < 0) {
return Rect.fromLTRB(size.width + offset, 0.0, size.width, size.height); return Rect.fromLTRB(size.width + offset, 0.0, size.width, size.height);
}
return Rect.fromLTRB(0.0, 0.0, offset, size.height); return Rect.fromLTRB(0.0, 0.0, offset, size.height);
case Axis.vertical: case Axis.vertical:
final double offset = moveAnimation.value.dy * size.height; final double offset = moveAnimation.value.dy * size.height;
if (offset < 0) if (offset < 0) {
return Rect.fromLTRB(0.0, size.height + offset, size.width, size.height); return Rect.fromLTRB(0.0, size.height + offset, size.width, size.height);
}
return Rect.fromLTRB(0.0, 0.0, size.width, offset); return Rect.fromLTRB(0.0, 0.0, size.width, offset);
} }
} }
...@@ -338,8 +340,9 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin ...@@ -338,8 +340,9 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
} }
DismissDirection _extentToDirection(double extent) { DismissDirection _extentToDirection(double extent) {
if (extent == 0.0) if (extent == 0.0) {
return DismissDirection.none; return DismissDirection.none;
}
if (_directionIsXAxis) { if (_directionIsXAxis) {
switch (Directionality.of(context)) { switch (Directionality.of(context)) {
case TextDirection.rtl: case TextDirection.rtl:
...@@ -363,8 +366,9 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin ...@@ -363,8 +366,9 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
} }
void _handleDragStart(DragStartDetails details) { void _handleDragStart(DragStartDetails details) {
if (_confirming) if (_confirming) {
return; return;
}
_dragUnderway = true; _dragUnderway = true;
if (_moveController!.isAnimating) { if (_moveController!.isAnimating) {
_dragExtent = _moveController!.value * _overallDragAxisExtent * _dragExtent.sign; _dragExtent = _moveController!.value * _overallDragAxisExtent * _dragExtent.sign;
...@@ -379,8 +383,9 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin ...@@ -379,8 +383,9 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
} }
void _handleDragUpdate(DragUpdateDetails details) { void _handleDragUpdate(DragUpdateDetails details) {
if (!_isActive || _moveController!.isAnimating) if (!_isActive || _moveController!.isAnimating) {
return; return;
}
final double delta = details.primaryDelta!; final double delta = details.primaryDelta!;
final double oldDragExtent = _dragExtent; final double oldDragExtent = _dragExtent;
...@@ -391,24 +396,28 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin ...@@ -391,24 +396,28 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
break; break;
case DismissDirection.up: case DismissDirection.up:
if (_dragExtent + delta < 0) if (_dragExtent + delta < 0) {
_dragExtent += delta; _dragExtent += delta;
}
break; break;
case DismissDirection.down: case DismissDirection.down:
if (_dragExtent + delta > 0) if (_dragExtent + delta > 0) {
_dragExtent += delta; _dragExtent += delta;
}
break; break;
case DismissDirection.endToStart: case DismissDirection.endToStart:
switch (Directionality.of(context)) { switch (Directionality.of(context)) {
case TextDirection.rtl: case TextDirection.rtl:
if (_dragExtent + delta > 0) if (_dragExtent + delta > 0) {
_dragExtent += delta; _dragExtent += delta;
}
break; break;
case TextDirection.ltr: case TextDirection.ltr:
if (_dragExtent + delta < 0) if (_dragExtent + delta < 0) {
_dragExtent += delta; _dragExtent += delta;
}
break; break;
} }
break; break;
...@@ -416,12 +425,14 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin ...@@ -416,12 +425,14 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
case DismissDirection.startToEnd: case DismissDirection.startToEnd:
switch (Directionality.of(context)) { switch (Directionality.of(context)) {
case TextDirection.rtl: case TextDirection.rtl:
if (_dragExtent + delta < 0) if (_dragExtent + delta < 0) {
_dragExtent += delta; _dragExtent += delta;
}
break; break;
case TextDirection.ltr: case TextDirection.ltr:
if (_dragExtent + delta > 0) if (_dragExtent + delta > 0) {
_dragExtent += delta; _dragExtent += delta;
}
break; break;
} }
break; break;
...@@ -481,25 +492,29 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin ...@@ -481,25 +492,29 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
DismissDirection flingDirection; DismissDirection flingDirection;
// Verify that the fling is in the generally right direction and fast enough. // Verify that the fling is in the generally right direction and fast enough.
if (_directionIsXAxis) { if (_directionIsXAxis) {
if (vx.abs() - vy.abs() < _kMinFlingVelocityDelta || vx.abs() < _kMinFlingVelocity) if (vx.abs() - vy.abs() < _kMinFlingVelocityDelta || vx.abs() < _kMinFlingVelocity) {
return _FlingGestureKind.none; return _FlingGestureKind.none;
}
assert(vx != 0.0); assert(vx != 0.0);
flingDirection = _extentToDirection(vx); flingDirection = _extentToDirection(vx);
} else { } else {
if (vy.abs() - vx.abs() < _kMinFlingVelocityDelta || vy.abs() < _kMinFlingVelocity) if (vy.abs() - vx.abs() < _kMinFlingVelocityDelta || vy.abs() < _kMinFlingVelocity) {
return _FlingGestureKind.none; return _FlingGestureKind.none;
}
assert(vy != 0.0); assert(vy != 0.0);
flingDirection = _extentToDirection(vy); flingDirection = _extentToDirection(vy);
} }
assert(_dismissDirection != null); assert(_dismissDirection != null);
if (flingDirection == _dismissDirection) if (flingDirection == _dismissDirection) {
return _FlingGestureKind.forward; return _FlingGestureKind.forward;
}
return _FlingGestureKind.reverse; return _FlingGestureKind.reverse;
} }
void _handleDragEnd(DragEndDetails details) { void _handleDragEnd(DragEndDetails details) {
if (!_isActive || _moveController!.isAnimating) if (!_isActive || _moveController!.isAnimating) {
return; return;
}
_dragUnderway = false; _dragUnderway = false;
if (_moveController!.isCompleted) { if (_moveController!.isCompleted) {
_handleMoveCompleted(); _handleMoveCompleted();
...@@ -551,12 +566,13 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin ...@@ -551,12 +566,13 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
} }
final bool result = await _confirmStartResizeAnimation(); final bool result = await _confirmStartResizeAnimation();
if (mounted) { if (mounted) {
if (result) if (result) {
_startResizeAnimation(); _startResizeAnimation();
else } else {
_moveController!.reverse(); _moveController!.reverse();
} }
} }
}
Future<bool> _confirmStartResizeAnimation() async { Future<bool> _confirmStartResizeAnimation() async {
if (widget.confirmDismiss != null) { if (widget.confirmDismiss != null) {
...@@ -618,9 +634,10 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin ...@@ -618,9 +634,10 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
Widget? background = widget.background; Widget? background = widget.background;
if (widget.secondaryBackground != null) { if (widget.secondaryBackground != null) {
final DismissDirection direction = _dismissDirection; final DismissDirection direction = _dismissDirection;
if (direction == DismissDirection.endToStart || direction == DismissDirection.up) if (direction == DismissDirection.endToStart || direction == DismissDirection.up) {
background = widget.secondaryBackground; background = widget.secondaryBackground;
} }
}
if (_resizeAnimation != null) { if (_resizeAnimation != null) {
// we've been dragged aside, and are now resizing. // we've been dragged aside, and are now resizing.
...@@ -672,8 +689,9 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin ...@@ -672,8 +689,9 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
// If the DismissDirection is none, we do not add drag gestures because the content // If the DismissDirection is none, we do not add drag gestures because the content
// cannot be dragged. // cannot be dragged.
if (widget.direction == DismissDirection.none) if (widget.direction == DismissDirection.none) {
return content; return content;
}
// We are not resizing but we may be being dragging in widget.direction. // We are not resizing but we may be being dragging in widget.direction.
return GestureDetector( return GestureDetector(
......
...@@ -479,8 +479,9 @@ class LongPressDraggable<T extends Object> extends Draggable<T> { ...@@ -479,8 +479,9 @@ class LongPressDraggable<T extends Object> extends Draggable<T> {
return DelayedMultiDragGestureRecognizer(delay: delay) return DelayedMultiDragGestureRecognizer(delay: delay)
..onStart = (Offset position) { ..onStart = (Offset position) {
final Drag? result = onStart(position); final Drag? result = onStart(position);
if (result != null && hapticFeedbackOnStart) if (result != null && hapticFeedbackOnStart) {
HapticFeedback.selectionClick(); HapticFeedback.selectionClick();
}
return result; return result;
}; };
} }
...@@ -518,21 +519,24 @@ class _DraggableState<T extends Object> extends State<Draggable<T>> { ...@@ -518,21 +519,24 @@ class _DraggableState<T extends Object> extends State<Draggable<T>> {
int _activeCount = 0; int _activeCount = 0;
void _disposeRecognizerIfInactive() { void _disposeRecognizerIfInactive() {
if (_activeCount > 0) if (_activeCount > 0) {
return; return;
}
_recognizer!.dispose(); _recognizer!.dispose();
_recognizer = null; _recognizer = null;
} }
void _routePointer(PointerDownEvent event) { void _routePointer(PointerDownEvent event) {
if (widget.maxSimultaneousDrags != null && _activeCount >= widget.maxSimultaneousDrags!) if (widget.maxSimultaneousDrags != null && _activeCount >= widget.maxSimultaneousDrags!) {
return; return;
}
_recognizer!.addPointer(event); _recognizer!.addPointer(event);
} }
_DragAvatar<T>? _startDrag(Offset position) { _DragAvatar<T>? _startDrag(Offset position) {
if (widget.maxSimultaneousDrags != null && _activeCount >= widget.maxSimultaneousDrags!) if (widget.maxSimultaneousDrags != null && _activeCount >= widget.maxSimultaneousDrags!) {
return null; return null;
}
final Offset dragStartPoint; final Offset dragStartPoint;
if (widget.dragAnchorStrategy == null) { if (widget.dragAnchorStrategy == null) {
switch (widget.dragAnchor) { switch (widget.dragAnchor) {
...@@ -580,10 +584,12 @@ class _DraggableState<T extends Object> extends State<Draggable<T>> { ...@@ -580,10 +584,12 @@ class _DraggableState<T extends Object> extends State<Draggable<T>> {
offset: offset, offset: offset,
)); ));
} }
if (wasAccepted && widget.onDragCompleted != null) if (wasAccepted && widget.onDragCompleted != null) {
widget.onDragCompleted!(); widget.onDragCompleted!();
if (!wasAccepted && widget.onDraggableCanceled != null) }
if (!wasAccepted && widget.onDraggableCanceled != null) {
widget.onDraggableCanceled!(velocity, offset); widget.onDraggableCanceled!(velocity, offset);
}
}, },
); );
widget.onDragStarted?.call(); widget.onDragStarted?.call();
...@@ -734,8 +740,9 @@ class _DragTargetState<T extends Object> extends State<DragTarget<T>> { ...@@ -734,8 +740,9 @@ class _DragTargetState<T extends Object> extends State<DragTarget<T>> {
// because dart doubles and ints are backed by the same kind of object on web. // because dart doubles and ints are backed by the same kind of object on web.
// JavaScript does not support integers. // JavaScript does not support integers.
bool isExpectedDataType(Object? data, Type type) { bool isExpectedDataType(Object? data, Type type) {
if (kIsWeb && ((type == int && T == double) || (type == double && T == int))) if (kIsWeb && ((type == int && T == double) || (type == double && T == int))) {
return false; return false;
}
return data is T?; return data is T?;
} }
...@@ -757,8 +764,9 @@ class _DragTargetState<T extends Object> extends State<DragTarget<T>> { ...@@ -757,8 +764,9 @@ class _DragTargetState<T extends Object> extends State<DragTarget<T>> {
void didLeave(_DragAvatar<Object> avatar) { void didLeave(_DragAvatar<Object> avatar) {
assert(_candidateAvatars.contains(avatar) || _rejectedAvatars.contains(avatar)); assert(_candidateAvatars.contains(avatar) || _rejectedAvatars.contains(avatar));
if (!mounted) if (!mounted) {
return; return;
}
setState(() { setState(() {
_candidateAvatars.remove(avatar); _candidateAvatars.remove(avatar);
_rejectedAvatars.remove(avatar); _rejectedAvatars.remove(avatar);
...@@ -768,8 +776,9 @@ class _DragTargetState<T extends Object> extends State<DragTarget<T>> { ...@@ -768,8 +776,9 @@ class _DragTargetState<T extends Object> extends State<DragTarget<T>> {
void didDrop(_DragAvatar<Object> avatar) { void didDrop(_DragAvatar<Object> avatar) {
assert(_candidateAvatars.contains(avatar)); assert(_candidateAvatars.contains(avatar));
if (!mounted) if (!mounted) {
return; return;
}
setState(() { setState(() {
_candidateAvatars.remove(avatar); _candidateAvatars.remove(avatar);
}); });
...@@ -778,8 +787,9 @@ class _DragTargetState<T extends Object> extends State<DragTarget<T>> { ...@@ -778,8 +787,9 @@ class _DragTargetState<T extends Object> extends State<DragTarget<T>> {
} }
void didMove(_DragAvatar<Object> avatar) { void didMove(_DragAvatar<Object> avatar) {
if (!mounted) if (!mounted) {
return; return;
}
widget.onMove?.call(DragTargetDetails<T>(data: avatar.data! as T, offset: avatar._lastOffset!)); widget.onMove?.call(DragTargetDetails<T>(data: avatar.data! as T, offset: avatar._lastOffset!));
} }
...@@ -898,8 +908,9 @@ class _DragAvatar<T extends Object> extends Drag { ...@@ -898,8 +908,9 @@ class _DragAvatar<T extends Object> extends Drag {
// Enter new targets. // Enter new targets.
final _DragTargetState<Object>? newTarget = targets.cast<_DragTargetState<Object>?>().firstWhere( final _DragTargetState<Object>? newTarget = targets.cast<_DragTargetState<Object>?>().firstWhere(
(_DragTargetState<Object>? target) { (_DragTargetState<Object>? target) {
if (target == null) if (target == null) {
return false; return false;
}
_enteredTargets.add(target); _enteredTargets.add(target);
return target.didEnter(this); return target.didEnter(this);
}, },
...@@ -922,16 +933,18 @@ class _DragAvatar<T extends Object> extends Drag { ...@@ -922,16 +933,18 @@ class _DragAvatar<T extends Object> extends Drag {
final HitTestTarget target = entry.target; final HitTestTarget target = entry.target;
if (target is RenderMetaData) { if (target is RenderMetaData) {
final dynamic metaData = target.metaData; final dynamic metaData = target.metaData;
if (metaData is _DragTargetState && metaData.isExpectedDataType(data, T)) if (metaData is _DragTargetState && metaData.isExpectedDataType(data, T)) {
targets.add(metaData); targets.add(metaData);
} }
} }
}
return targets; return targets;
} }
void _leaveAllEntered() { void _leaveAllEntered() {
for (int i = 0; i < _enteredTargets.length; i += 1) for (int i = 0; i < _enteredTargets.length; i += 1) {
_enteredTargets[i].didLeave(this); _enteredTargets[i].didLeave(this);
}
_enteredTargets.clear(); _enteredTargets.clear();
} }
......
...@@ -753,9 +753,10 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier { ...@@ -753,9 +753,10 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier {
/// Use [nearestScope] to start at this node instead of above it. /// Use [nearestScope] to start at this node instead of above it.
FocusScopeNode? get enclosingScope { FocusScopeNode? get enclosingScope {
for (final FocusNode node in ancestors) { for (final FocusNode node in ancestors) {
if (node is FocusScopeNode) if (node is FocusScopeNode) {
return node; return node;
} }
}
return null; return null;
} }
...@@ -1319,8 +1320,9 @@ class FocusScopeNode extends FocusNode { ...@@ -1319,8 +1320,9 @@ class FocusScopeNode extends FocusNode {
assert(findFirstFocus != null); assert(findFirstFocus != null);
// It is possible that a previously focused child is no longer focusable. // It is possible that a previously focused child is no longer focusable.
while (this.focusedChild != null && !this.focusedChild!.canRequestFocus) while (this.focusedChild != null && !this.focusedChild!.canRequestFocus) {
_focusedChildren.removeLast(); _focusedChildren.removeLast();
}
final FocusNode? focusedChild = this.focusedChild; final FocusNode? focusedChild = this.focusedChild;
// If findFirstFocus is false, then the request is to make this scope the // If findFirstFocus is false, then the request is to make this scope the
......
...@@ -156,9 +156,10 @@ class FormState extends State<Form> { ...@@ -156,9 +156,10 @@ class FormState extends State<Form> {
/// Saves every [FormField] that is a descendant of this [Form]. /// Saves every [FormField] that is a descendant of this [Form].
void save() { void save() {
for (final FormFieldState<dynamic> field in _fields) for (final FormFieldState<dynamic> field in _fields) {
field.save(); field.save();
} }
}
/// Resets every [FormField] that is a descendant of this [Form] back to its /// Resets every [FormField] that is a descendant of this [Form] back to its
/// [FormField.initialValue]. /// [FormField.initialValue].
...@@ -168,8 +169,9 @@ class FormState extends State<Form> { ...@@ -168,8 +169,9 @@ class FormState extends State<Form> {
/// If the form's [Form.autovalidateMode] property is [AutovalidateMode.always], /// If the form's [Form.autovalidateMode] property is [AutovalidateMode.always],
/// the fields will all be revalidated after being reset. /// the fields will all be revalidated after being reset.
void reset() { void reset() {
for (final FormFieldState<dynamic> field in _fields) for (final FormFieldState<dynamic> field in _fields) {
field.reset(); field.reset();
}
_hasInteractedByUser = false; _hasInteractedByUser = false;
_fieldDidChange(); _fieldDidChange();
} }
...@@ -186,8 +188,9 @@ class FormState extends State<Form> { ...@@ -186,8 +188,9 @@ class FormState extends State<Form> {
bool _validate() { bool _validate() {
bool hasError = false; bool hasError = false;
for (final FormFieldState<dynamic> field in _fields) for (final FormFieldState<dynamic> field in _fields) {
hasError = !field.validate() || hasError; hasError = !field.validate() || hasError;
}
return !hasError; return !hasError;
} }
} }
...@@ -391,9 +394,10 @@ class FormFieldState<T> extends State<FormField<T>> with RestorationMixin { ...@@ -391,9 +394,10 @@ class FormFieldState<T> extends State<FormField<T>> with RestorationMixin {
} }
void _validate() { void _validate() {
if (widget.validator != null) if (widget.validator != null) {
_errorText.value = widget.validator!(_value); _errorText.value = widget.validator!(_value);
} }
}
/// Updates this field's state to the new value. Useful for responding to /// Updates this field's state to the new value. Useful for responding to
/// child widget changes, e.g. [Slider]'s [Slider.onChanged] argument. /// child widget changes, e.g. [Slider]'s [Slider.onChanged] argument.
......
...@@ -1434,8 +1434,9 @@ class RawGestureDetectorState extends State<RawGestureDetector> { ...@@ -1434,8 +1434,9 @@ class RawGestureDetectorState extends State<RawGestureDetector> {
/// If this is never called, then the actions are not filtered. If the list of /// If this is never called, then the actions are not filtered. If the list of
/// actions to filter changes, it must be called again. /// actions to filter changes, it must be called again.
void replaceSemanticsActions(Set<SemanticsAction> actions) { void replaceSemanticsActions(Set<SemanticsAction> actions) {
if (widget.excludeFromSemantics) if (widget.excludeFromSemantics) {
return; return;
}
final RenderSemanticsGestureHandler? semanticsGestureHandler = context.findRenderObject() as RenderSemanticsGestureHandler?; final RenderSemanticsGestureHandler? semanticsGestureHandler = context.findRenderObject() as RenderSemanticsGestureHandler?;
assert(() { assert(() {
...@@ -1453,8 +1454,9 @@ class RawGestureDetectorState extends State<RawGestureDetector> { ...@@ -1453,8 +1454,9 @@ class RawGestureDetectorState extends State<RawGestureDetector> {
@override @override
void dispose() { void dispose() {
for (final GestureRecognizer recognizer in _recognizers!.values) for (final GestureRecognizer recognizer in _recognizers!.values) {
recognizer.dispose(); recognizer.dispose();
}
_recognizers = null; _recognizers = null;
super.dispose(); super.dispose();
} }
...@@ -1472,16 +1474,18 @@ class RawGestureDetectorState extends State<RawGestureDetector> { ...@@ -1472,16 +1474,18 @@ class RawGestureDetectorState extends State<RawGestureDetector> {
gestures[type]!.initializer(_recognizers![type]!); gestures[type]!.initializer(_recognizers![type]!);
} }
for (final Type type in oldRecognizers.keys) { for (final Type type in oldRecognizers.keys) {
if (!_recognizers!.containsKey(type)) if (!_recognizers!.containsKey(type)) {
oldRecognizers[type]!.dispose(); oldRecognizers[type]!.dispose();
} }
} }
}
void _handlePointerDown(PointerDownEvent event) { void _handlePointerDown(PointerDownEvent event) {
assert(_recognizers != null); assert(_recognizers != null);
for (final GestureRecognizer recognizer in _recognizers!.values) for (final GestureRecognizer recognizer in _recognizers!.values) {
recognizer.addPointer(event); recognizer.addPointer(event);
} }
}
void _handlePointerPanZoomStart(PointerPanZoomStartEvent event) { void _handlePointerPanZoomStart(PointerPanZoomStartEvent event) {
assert(_recognizers != null); assert(_recognizers != null);
...@@ -1611,8 +1615,9 @@ class _DefaultSemanticsGestureDelegate extends SemanticsGestureDelegate { ...@@ -1611,8 +1615,9 @@ class _DefaultSemanticsGestureDelegate extends SemanticsGestureDelegate {
GestureTapCallback? _getTapHandler(Map<Type, GestureRecognizer> recognizers) { GestureTapCallback? _getTapHandler(Map<Type, GestureRecognizer> recognizers) {
final TapGestureRecognizer? tap = recognizers[TapGestureRecognizer] as TapGestureRecognizer?; final TapGestureRecognizer? tap = recognizers[TapGestureRecognizer] as TapGestureRecognizer?;
if (tap == null) if (tap == null) {
return null; return null;
}
return () { return () {
assert(tap != null); assert(tap != null);
...@@ -1624,8 +1629,9 @@ class _DefaultSemanticsGestureDelegate extends SemanticsGestureDelegate { ...@@ -1624,8 +1629,9 @@ class _DefaultSemanticsGestureDelegate extends SemanticsGestureDelegate {
GestureLongPressCallback? _getLongPressHandler(Map<Type, GestureRecognizer> recognizers) { GestureLongPressCallback? _getLongPressHandler(Map<Type, GestureRecognizer> recognizers) {
final LongPressGestureRecognizer? longPress = recognizers[LongPressGestureRecognizer] as LongPressGestureRecognizer?; final LongPressGestureRecognizer? longPress = recognizers[LongPressGestureRecognizer] as LongPressGestureRecognizer?;
if (longPress == null) if (longPress == null) {
return null; return null;
}
return () { return () {
longPress.onLongPressDown?.call(const LongPressDownDetails()); longPress.onLongPressDown?.call(const LongPressDownDetails());
...@@ -1658,13 +1664,16 @@ class _DefaultSemanticsGestureDelegate extends SemanticsGestureDelegate { ...@@ -1658,13 +1664,16 @@ class _DefaultSemanticsGestureDelegate extends SemanticsGestureDelegate {
pan.onEnd?.call(DragEndDetails()); pan.onEnd?.call(DragEndDetails());
}; };
if (horizontalHandler == null && panHandler == null) if (horizontalHandler == null && panHandler == null) {
return null; return null;
}
return (DragUpdateDetails details) { return (DragUpdateDetails details) {
if (horizontalHandler != null) if (horizontalHandler != null) {
horizontalHandler(details); horizontalHandler(details);
if (panHandler != null) }
if (panHandler != null) {
panHandler(details); panHandler(details);
}
}; };
} }
...@@ -1690,13 +1699,16 @@ class _DefaultSemanticsGestureDelegate extends SemanticsGestureDelegate { ...@@ -1690,13 +1699,16 @@ class _DefaultSemanticsGestureDelegate extends SemanticsGestureDelegate {
pan.onEnd?.call(DragEndDetails()); pan.onEnd?.call(DragEndDetails());
}; };
if (verticalHandler == null && panHandler == null) if (verticalHandler == null && panHandler == null) {
return null; return null;
}
return (DragUpdateDetails details) { return (DragUpdateDetails details) {
if (verticalHandler != null) if (verticalHandler != null) {
verticalHandler(details); verticalHandler(details);
if (panHandler != null) }
if (panHandler != null) {
panHandler(details); panHandler(details);
}
}; };
} }
} }
...@@ -378,8 +378,9 @@ class _HeroState extends State<Hero> { ...@@ -378,8 +378,9 @@ class _HeroState extends State<Hero> {
// This method can be safely called even when this [Hero] is currently not in // This method can be safely called even when this [Hero] is currently not in
// a flight. // a flight.
void endFlight({ bool keepPlaceholder = false }) { void endFlight({ bool keepPlaceholder = false }) {
if (keepPlaceholder || _placeholderSize == null) if (keepPlaceholder || _placeholderSize == null) {
return; return;
}
_placeholderSize = null; _placeholderSize = null;
if (mounted) { if (mounted) {
...@@ -590,8 +591,9 @@ class _HeroFlight { ...@@ -590,8 +591,9 @@ class _HeroFlight {
return; return;
} }
if (_scheduledPerformAnimationUpdate) if (_scheduledPerformAnimationUpdate) {
return; return;
}
// The `navigator` must be non-null here, or the first if clause above would // The `navigator` must be non-null here, or the first if clause above would
// have returned from this method. // have returned from this method.
...@@ -730,10 +732,11 @@ class _HeroFlight { ...@@ -730,10 +732,11 @@ class _HeroFlight {
); );
shuttle = null; shuttle = null;
if (newManifest.type == HeroFlightDirection.pop) if (newManifest.type == HeroFlightDirection.pop) {
_proxyAnimation.parent = ReverseAnimation(newManifest.animation); _proxyAnimation.parent = ReverseAnimation(newManifest.animation);
else } else {
_proxyAnimation.parent = newManifest.animation; _proxyAnimation.parent = newManifest.animation;
}
manifest.fromHero.endFlight(keepPlaceholder: true); manifest.fromHero.endFlight(keepPlaceholder: true);
manifest.toHero.endFlight(keepPlaceholder: true); manifest.toHero.endFlight(keepPlaceholder: true);
...@@ -796,9 +799,10 @@ class HeroController extends NavigatorObserver { ...@@ -796,9 +799,10 @@ class HeroController extends NavigatorObserver {
assert(route != null); assert(route != null);
// Don't trigger another flight when a pop is committed as a user gesture // Don't trigger another flight when a pop is committed as a user gesture
// back swipe is snapped. // back swipe is snapped.
if (!navigator!.userGestureInProgress) if (!navigator!.userGestureInProgress) {
_maybeStartHeroTransition(route, previousRoute, HeroFlightDirection.pop, false); _maybeStartHeroTransition(route, previousRoute, HeroFlightDirection.pop, false);
} }
}
@override @override
void didReplace({ Route<dynamic>? newRoute, Route<dynamic>? oldRoute }) { void didReplace({ Route<dynamic>? newRoute, Route<dynamic>? oldRoute }) {
...@@ -818,8 +822,9 @@ class HeroController extends NavigatorObserver { ...@@ -818,8 +822,9 @@ class HeroController extends NavigatorObserver {
@override @override
void didStopUserGesture() { void didStopUserGesture() {
if (navigator!.userGestureInProgress) if (navigator!.userGestureInProgress) {
return; return;
}
// When the user gesture ends, if the user horizontal drag gesture initiated // When the user gesture ends, if the user horizontal drag gesture initiated
// the flight (i.e. the back swipe) didn't move towards the pop direction at // the flight (i.e. the back swipe) didn't move towards the pop direction at
...@@ -908,8 +913,9 @@ class HeroController extends NavigatorObserver { ...@@ -908,8 +913,9 @@ class HeroController extends NavigatorObserver {
// callback was called, then don't actually start a transition, and we don' // callback was called, then don't actually start a transition, and we don'
// t have to worry about any Hero widget we might have hidden in a previous // t have to worry about any Hero widget we might have hidden in a previous
// flight, or ongoing flights. // flight, or ongoing flights.
if (navigator == null || overlay == null) if (navigator == null || overlay == null) {
return; return;
}
final RenderObject? navigatorRenderObject = navigator.context.findRenderObject(); final RenderObject? navigatorRenderObject = navigator.context.findRenderObject();
...@@ -975,9 +981,10 @@ class HeroController extends NavigatorObserver { ...@@ -975,9 +981,10 @@ class HeroController extends NavigatorObserver {
// This can happen in a route pop transition when a fromHero is no longer // This can happen in a route pop transition when a fromHero is no longer
// mounted, or kept alive by the [KeepAlive] mechanism but no longer visible. // mounted, or kept alive by the [KeepAlive] mechanism but no longer visible.
// TODO(LongCatIsLooong): resume aborted flights: https://github.com/flutter/flutter/issues/72947 // TODO(LongCatIsLooong): resume aborted flights: https://github.com/flutter/flutter/issues/72947
for (final _HeroState toHero in toHeroes.values) for (final _HeroState toHero in toHeroes.values) {
toHero.endFlight(); toHero.endFlight();
} }
}
void _handleFlightEnded(_HeroFlight flight) { void _handleFlightEnded(_HeroFlight flight) {
_flights.remove(flight.manifest.tag); _flights.remove(flight.manifest.tag);
......
...@@ -181,8 +181,9 @@ class Icon extends StatelessWidget { ...@@ -181,8 +181,9 @@ class Icon extends StatelessWidget {
final double iconOpacity = iconTheme.opacity ?? 1.0; final double iconOpacity = iconTheme.opacity ?? 1.0;
Color iconColor = color ?? iconTheme.color!; Color iconColor = color ?? iconTheme.color!;
if (iconOpacity != 1.0) if (iconOpacity != 1.0) {
iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity); iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity);
}
Widget iconWidget = RichText( Widget iconWidget = RichText(
overflow: TextOverflow.visible, // Never clip. overflow: TextOverflow.visible, // Never clip.
......
...@@ -49,8 +49,9 @@ class IconData { ...@@ -49,8 +49,9 @@ class IconData {
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
if (other.runtimeType != runtimeType) if (other.runtimeType != runtimeType) {
return false; return false;
}
return other is IconData return other is IconData
&& other.codePoint == codePoint && other.codePoint == codePoint
&& other.fontFamily == fontFamily && other.fontFamily == fontFamily
......
...@@ -49,8 +49,9 @@ class IconThemeData with Diagnosticable { ...@@ -49,8 +49,9 @@ class IconThemeData with Diagnosticable {
/// replaced by the non-null parameters of the given icon theme. If the given /// replaced by the non-null parameters of the given icon theme. If the given
/// icon theme is null, simply returns this icon theme. /// icon theme is null, simply returns this icon theme.
IconThemeData merge(IconThemeData? other) { IconThemeData merge(IconThemeData? other) {
if (other == null) if (other == null) {
return this; return this;
}
return copyWith( return copyWith(
color: other.color, color: other.color,
opacity: other.opacity, opacity: other.opacity,
...@@ -108,8 +109,9 @@ class IconThemeData with Diagnosticable { ...@@ -108,8 +109,9 @@ class IconThemeData with Diagnosticable {
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
if (other.runtimeType != runtimeType) if (other.runtimeType != runtimeType) {
return false; return false;
}
return other is IconThemeData return other is IconThemeData
&& other.color == color && other.color == color
&& other.opacity == opacity && other.opacity == opacity
......
...@@ -1065,10 +1065,11 @@ class _ImageState extends State<Image> with WidgetsBindingObserver { ...@@ -1065,10 +1065,11 @@ class _ImageState extends State<Image> with WidgetsBindingObserver {
_updateInvertColors(); _updateInvertColors();
_resolveImage(); _resolveImage();
if (TickerMode.of(context)) if (TickerMode.of(context)) {
_listenToStream(); _listenToStream();
else } else {
_stopListeningToStream(keepStreamAlive: true); _stopListeningToStream(keepStreamAlive: true);
}
super.didChangeDependencies(); super.didChangeDependencies();
} }
...@@ -1082,9 +1083,10 @@ class _ImageState extends State<Image> with WidgetsBindingObserver { ...@@ -1082,9 +1083,10 @@ class _ImageState extends State<Image> with WidgetsBindingObserver {
_imageStream!.addListener(_getListener(recreateListener: true)); _imageStream!.addListener(_getListener(recreateListener: true));
_imageStream!.removeListener(oldListener); _imageStream!.removeListener(oldListener);
} }
if (widget.image != oldWidget.image) if (widget.image != oldWidget.image) {
_resolveImage(); _resolveImage();
} }
}
@override @override
void didChangeAccessibilityFeatures() { void didChangeAccessibilityFeatures() {
...@@ -1176,14 +1178,17 @@ class _ImageState extends State<Image> with WidgetsBindingObserver { ...@@ -1176,14 +1178,17 @@ class _ImageState extends State<Image> with WidgetsBindingObserver {
// registration from the old stream to the new stream (if a listener was // registration from the old stream to the new stream (if a listener was
// registered). // registered).
void _updateSourceStream(ImageStream newStream) { void _updateSourceStream(ImageStream newStream) {
if (_imageStream?.key == newStream.key) if (_imageStream?.key == newStream.key) {
return; return;
}
if (_isListeningToStream) if (_isListeningToStream) {
_imageStream!.removeListener(_getListener()); _imageStream!.removeListener(_getListener());
}
if (!widget.gaplessPlayback) if (!widget.gaplessPlayback) {
setState(() { _replaceImage(info: null); }); setState(() { _replaceImage(info: null); });
}
setState(() { setState(() {
_loadingProgress = null; _loadingProgress = null;
...@@ -1192,13 +1197,15 @@ class _ImageState extends State<Image> with WidgetsBindingObserver { ...@@ -1192,13 +1197,15 @@ class _ImageState extends State<Image> with WidgetsBindingObserver {
}); });
_imageStream = newStream; _imageStream = newStream;
if (_isListeningToStream) if (_isListeningToStream) {
_imageStream!.addListener(_getListener()); _imageStream!.addListener(_getListener());
} }
}
void _listenToStream() { void _listenToStream() {
if (_isListeningToStream) if (_isListeningToStream) {
return; return;
}
_imageStream!.addListener(_getListener()); _imageStream!.addListener(_getListener());
_completerHandle?.dispose(); _completerHandle?.dispose();
...@@ -1215,8 +1222,9 @@ class _ImageState extends State<Image> with WidgetsBindingObserver { ...@@ -1215,8 +1222,9 @@ class _ImageState extends State<Image> with WidgetsBindingObserver {
/// to true, which create [ImageStreamCompleterHandle] to keep the completer /// to true, which create [ImageStreamCompleterHandle] to keep the completer
/// alive and is compatible with the [TickerMode] being off. /// alive and is compatible with the [TickerMode] being off.
void _stopListeningToStream({bool keepStreamAlive = false}) { void _stopListeningToStream({bool keepStreamAlive = false}) {
if (!_isListeningToStream) if (!_isListeningToStream) {
return; return;
}
if (keepStreamAlive && _completerHandle == null && _imageStream?.completer != null) { if (keepStreamAlive && _completerHandle == null && _imageStream?.completer != null) {
_completerHandle = _imageStream!.completer!.keepAlive(); _completerHandle = _imageStream!.completer!.keepAlive();
...@@ -1257,11 +1265,13 @@ class _ImageState extends State<Image> with WidgetsBindingObserver { ...@@ -1257,11 +1265,13 @@ class _ImageState extends State<Image> with WidgetsBindingObserver {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (_lastException != null) { if (_lastException != null) {
if (widget.errorBuilder != null) if (widget.errorBuilder != null) {
return widget.errorBuilder!(context, _lastException!, _lastStack); return widget.errorBuilder!(context, _lastException!, _lastStack);
if (kDebugMode) }
if (kDebugMode) {
return _debugBuildErrorWidget(context, _lastException!); return _debugBuildErrorWidget(context, _lastException!);
} }
}
Widget result = RawImage( Widget result = RawImage(
// Do not clone the image, because RawImage is a stateless wrapper. // Do not clone the image, because RawImage is a stateless wrapper.
...@@ -1295,11 +1305,13 @@ class _ImageState extends State<Image> with WidgetsBindingObserver { ...@@ -1295,11 +1305,13 @@ class _ImageState extends State<Image> with WidgetsBindingObserver {
); );
} }
if (widget.frameBuilder != null) if (widget.frameBuilder != null) {
result = widget.frameBuilder!(context, result, _frameNumber, _wasSynchronouslyLoaded); result = widget.frameBuilder!(context, result, _frameNumber, _wasSynchronouslyLoaded);
}
if (widget.loadingBuilder != null) if (widget.loadingBuilder != null) {
result = widget.loadingBuilder!(context, result, _loadingProgress); result = widget.loadingBuilder!(context, result, _loadingProgress);
}
return result; return result;
} }
......
...@@ -69,17 +69,19 @@ class ImageIcon extends StatelessWidget { ...@@ -69,17 +69,19 @@ class ImageIcon extends StatelessWidget {
final IconThemeData iconTheme = IconTheme.of(context); final IconThemeData iconTheme = IconTheme.of(context);
final double? iconSize = size ?? iconTheme.size; final double? iconSize = size ?? iconTheme.size;
if (image == null) if (image == null) {
return Semantics( return Semantics(
label: semanticLabel, label: semanticLabel,
child: SizedBox(width: iconSize, height: iconSize), child: SizedBox(width: iconSize, height: iconSize),
); );
}
final double? iconOpacity = iconTheme.opacity; final double? iconOpacity = iconTheme.opacity;
Color iconColor = color ?? iconTheme.color!; Color iconColor = color ?? iconTheme.color!;
if (iconOpacity != null && iconOpacity != 1.0) if (iconOpacity != null && iconOpacity != 1.0) {
iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity); iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity);
}
return Semantics( return Semantics(
label: semanticLabel, label: semanticLabel,
......
...@@ -415,8 +415,9 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget> ...@@ -415,8 +415,9 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget>
} }
void _updateTween(Tween<dynamic>? tween, dynamic targetValue) { void _updateTween(Tween<dynamic>? tween, dynamic targetValue) {
if (tween == null) if (tween == null) {
return; return;
}
tween tween
..begin = tween.evaluate(_animation) ..begin = tween.evaluate(_animation)
..end = targetValue; ..end = targetValue;
...@@ -427,10 +428,11 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget> ...@@ -427,10 +428,11 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget>
forEachTween((Tween<dynamic>? tween, dynamic targetValue, TweenConstructor<dynamic> constructor) { forEachTween((Tween<dynamic>? tween, dynamic targetValue, TweenConstructor<dynamic> constructor) {
if (targetValue != null) { if (targetValue != null) {
tween ??= constructor(targetValue); tween ??= constructor(targetValue);
if (_shouldAnimateTween(tween, targetValue)) if (_shouldAnimateTween(tween, targetValue)) {
shouldStartAnimation = true; shouldStartAnimation = true;
else } else {
tween.end ??= tween.begin; tween.end ??= tween.begin;
}
} else { } else {
tween = null; tween = null;
} }
......
...@@ -119,23 +119,26 @@ abstract class InheritedModel<T> extends InheritedWidget { ...@@ -119,23 +119,26 @@ abstract class InheritedModel<T> extends InheritedWidget {
// with the one that supports the specified model [aspect]. // with the one that supports the specified model [aspect].
static void _findModels<T extends InheritedModel<Object>>(BuildContext context, Object aspect, List<InheritedElement> results) { static void _findModels<T extends InheritedModel<Object>>(BuildContext context, Object aspect, List<InheritedElement> results) {
final InheritedElement? model = context.getElementForInheritedWidgetOfExactType<T>(); final InheritedElement? model = context.getElementForInheritedWidgetOfExactType<T>();
if (model == null) if (model == null) {
return; return;
}
results.add(model); results.add(model);
assert(model.widget is T); assert(model.widget is T);
final T modelWidget = model.widget as T; final T modelWidget = model.widget as T;
if (modelWidget.isSupportedAspect(aspect)) if (modelWidget.isSupportedAspect(aspect)) {
return; return;
}
Element? modelParent; Element? modelParent;
model.visitAncestorElements((Element ancestor) { model.visitAncestorElements((Element ancestor) {
modelParent = ancestor; modelParent = ancestor;
return false; return false;
}); });
if (modelParent == null) if (modelParent == null) {
return; return;
}
_findModels<T>(modelParent!, aspect, results); _findModels<T>(modelParent!, aspect, results);
} }
...@@ -156,8 +159,9 @@ abstract class InheritedModel<T> extends InheritedWidget { ...@@ -156,8 +159,9 @@ abstract class InheritedModel<T> extends InheritedWidget {
/// ///
/// If no ancestor of type T exists, null is returned. /// If no ancestor of type T exists, null is returned.
static T? inheritFrom<T extends InheritedModel<Object>>(BuildContext context, { Object? aspect }) { static T? inheritFrom<T extends InheritedModel<Object>>(BuildContext context, { Object? aspect }) {
if (aspect == null) if (aspect == null) {
return context.dependOnInheritedWidgetOfExactType<T>(); return context.dependOnInheritedWidgetOfExactType<T>();
}
// Create a dependency on all of the type T ancestor models up until // Create a dependency on all of the type T ancestor models up until
// a model is found for which isSupportedAspect(aspect) is true. // a model is found for which isSupportedAspect(aspect) is true.
...@@ -170,9 +174,10 @@ abstract class InheritedModel<T> extends InheritedWidget { ...@@ -170,9 +174,10 @@ abstract class InheritedModel<T> extends InheritedWidget {
final InheritedElement lastModel = models.last; final InheritedElement lastModel = models.last;
for (final InheritedElement model in models) { for (final InheritedElement model in models) {
final T value = context.dependOnInheritedElement(model, aspect: aspect) as T; final T value = context.dependOnInheritedElement(model, aspect: aspect) as T;
if (model == lastModel) if (model == lastModel) {
return value; return value;
} }
}
assert(false); assert(false);
return null; return null;
...@@ -187,8 +192,9 @@ class InheritedModelElement<T> extends InheritedElement { ...@@ -187,8 +192,9 @@ class InheritedModelElement<T> extends InheritedElement {
@override @override
void updateDependencies(Element dependent, Object? aspect) { void updateDependencies(Element dependent, Object? aspect) {
final Set<T>? dependencies = getDependencies(dependent) as Set<T>?; final Set<T>? dependencies = getDependencies(dependent) as Set<T>?;
if (dependencies != null && dependencies.isEmpty) if (dependencies != null && dependencies.isEmpty) {
return; return;
}
if (aspect == null) { if (aspect == null) {
setDependencies(dependent, HashSet<T>()); setDependencies(dependent, HashSet<T>());
...@@ -201,9 +207,11 @@ class InheritedModelElement<T> extends InheritedElement { ...@@ -201,9 +207,11 @@ class InheritedModelElement<T> extends InheritedElement {
@override @override
void notifyDependent(InheritedModel<T> oldWidget, Element dependent) { void notifyDependent(InheritedModel<T> oldWidget, Element dependent) {
final Set<T>? dependencies = getDependencies(dependent) as Set<T>?; final Set<T>? dependencies = getDependencies(dependent) as Set<T>?;
if (dependencies == null) if (dependencies == null) {
return; return;
if (dependencies.isEmpty || (widget as InheritedModel<T>).updateShouldNotifyDependent(oldWidget, dependencies)) }
if (dependencies.isEmpty || (widget as InheritedModel<T>).updateShouldNotifyDependent(oldWidget, dependencies)) {
dependent.didChangeDependencies(); dependent.didChangeDependencies();
} }
}
} }
...@@ -109,8 +109,9 @@ class _InheritedNotifierElement<T extends Listenable> extends InheritedElement { ...@@ -109,8 +109,9 @@ class _InheritedNotifierElement<T extends Listenable> extends InheritedElement {
@override @override
Widget build() { Widget build() {
if (_dirty) if (_dirty) {
notifyClients(widget as InheritedNotifier<T>); notifyClients(widget as InheritedNotifier<T>);
}
return super.build(); return super.build();
} }
......
...@@ -153,8 +153,9 @@ class _CaptureAll extends StatelessWidget { ...@@ -153,8 +153,9 @@ class _CaptureAll extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget wrappedChild = child; Widget wrappedChild = child;
for (final InheritedTheme theme in themes) for (final InheritedTheme theme in themes) {
wrappedChild = theme.wrap(context, wrappedChild); wrappedChild = theme.wrap(context, wrappedChild);
}
return wrappedChild; return wrappedChild;
} }
} }
...@@ -63,9 +63,10 @@ class _LayoutBuilderElement<ConstraintType extends Constraints> extends RenderOb ...@@ -63,9 +63,10 @@ class _LayoutBuilderElement<ConstraintType extends Constraints> extends RenderOb
@override @override
void visitChildren(ElementVisitor visitor) { void visitChildren(ElementVisitor visitor) {
if (_child != null) if (_child != null) {
visitor(_child!); visitor(_child!);
} }
}
@override @override
void forgetChild(Element child) { void forgetChild(Element child) {
...@@ -183,8 +184,9 @@ mixin RenderConstrainedLayoutBuilder<ConstraintType extends Constraints, ChildTy ...@@ -183,8 +184,9 @@ mixin RenderConstrainedLayoutBuilder<ConstraintType extends Constraints, ChildTy
LayoutCallback<ConstraintType>? _callback; LayoutCallback<ConstraintType>? _callback;
/// Change the layout callback. /// Change the layout callback.
void updateCallback(LayoutCallback<ConstraintType>? value) { void updateCallback(LayoutCallback<ConstraintType>? value) {
if (value == _callback) if (value == _callback) {
return; return;
}
_callback = value; _callback = value;
markNeedsLayout(); markNeedsLayout();
} }
...@@ -322,8 +324,9 @@ class _RenderLayoutBuilder extends RenderBox with RenderObjectWithChildMixin<Ren ...@@ -322,8 +324,9 @@ class _RenderLayoutBuilder extends RenderBox with RenderObjectWithChildMixin<Ren
@override @override
double? computeDistanceToActualBaseline(TextBaseline baseline) { double? computeDistanceToActualBaseline(TextBaseline baseline) {
if (child != null) if (child != null) {
return child!.getDistanceToActualBaseline(baseline); return child!.getDistanceToActualBaseline(baseline);
}
return super.computeDistanceToActualBaseline(baseline); return super.computeDistanceToActualBaseline(baseline);
} }
...@@ -334,9 +337,10 @@ class _RenderLayoutBuilder extends RenderBox with RenderObjectWithChildMixin<Ren ...@@ -334,9 +337,10 @@ class _RenderLayoutBuilder extends RenderBox with RenderObjectWithChildMixin<Ren
@override @override
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) if (child != null) {
context.paintChild(child!, offset); context.paintChild(child!, offset);
} }
}
bool _debugThrowIfNotCheckingIntrinsics() { bool _debugThrowIfNotCheckingIntrinsics() {
assert(() { assert(() {
......
...@@ -91,8 +91,9 @@ class ListWheelChildListDelegate extends ListWheelChildDelegate { ...@@ -91,8 +91,9 @@ class ListWheelChildListDelegate extends ListWheelChildDelegate {
@override @override
Widget? build(BuildContext context, int index) { Widget? build(BuildContext context, int index) {
if (index < 0 || index >= children.length) if (index < 0 || index >= children.length) {
return null; return null;
}
return IndexedSemantics(index: index, child: children[index]); return IndexedSemantics(index: index, child: children[index]);
} }
...@@ -137,8 +138,9 @@ class ListWheelChildLoopingListDelegate extends ListWheelChildDelegate { ...@@ -137,8 +138,9 @@ class ListWheelChildLoopingListDelegate extends ListWheelChildDelegate {
@override @override
Widget? build(BuildContext context, int index) { Widget? build(BuildContext context, int index) {
if (children.isEmpty) if (children.isEmpty) {
return null; return null;
}
return IndexedSemantics(index: index, child: children[index % children.length]); return IndexedSemantics(index: index, child: children[index % children.length]);
} }
...@@ -184,8 +186,9 @@ class ListWheelChildBuilderDelegate extends ListWheelChildDelegate { ...@@ -184,8 +186,9 @@ class ListWheelChildBuilderDelegate extends ListWheelChildDelegate {
final Widget? child = builder(context, index); final Widget? child = builder(context, index);
return child == null ? null : IndexedSemantics(index: index, child: child); return child == null ? null : IndexedSemantics(index: index, child: child);
} }
if (index < 0 || index >= childCount!) if (index < 0 || index >= childCount!) {
return null; return null;
}
return IndexedSemantics(index: index, child: builder(context, index)); return IndexedSemantics(index: index, child: builder(context, index));
} }
...@@ -830,8 +833,9 @@ class ListWheelElement extends RenderObjectElement implements ListWheelChildMana ...@@ -830,8 +833,9 @@ class ListWheelElement extends RenderObjectElement implements ListWheelChildMana
void performRebuild() { void performRebuild() {
_childWidgets.clear(); _childWidgets.clear();
super.performRebuild(); super.performRebuild();
if (_childElements.isEmpty) if (_childElements.isEmpty) {
return; return;
}
final int firstIndex = _childElements.firstKey()!; final int firstIndex = _childElements.firstKey()!;
final int lastIndex = _childElements.lastKey()!; final int lastIndex = _childElements.lastKey()!;
...@@ -892,9 +896,10 @@ class ListWheelElement extends RenderObjectElement implements ListWheelChildMana ...@@ -892,9 +896,10 @@ class ListWheelElement extends RenderObjectElement implements ListWheelChildMana
final ListWheelParentData? newParentData = newChild?.renderObject?.parentData as ListWheelParentData?; final ListWheelParentData? newParentData = newChild?.renderObject?.parentData as ListWheelParentData?;
if (newParentData != null) { if (newParentData != null) {
newParentData.index = newSlot! as int; newParentData.index = newSlot! as int;
if (oldParentData != null) if (oldParentData != null) {
newParentData.offset = oldParentData.offset; newParentData.offset = oldParentData.offset;
} }
}
return newChild; return newChild;
} }
......
...@@ -68,8 +68,9 @@ Future<Map<Type, dynamic>> _loadAll(Locale locale, Iterable<LocalizationsDelegat ...@@ -68,8 +68,9 @@ Future<Map<Type, dynamic>> _loadAll(Locale locale, Iterable<LocalizationsDelegat
} }
// All of the delegate.load() values were synchronous futures, we're done. // All of the delegate.load() values were synchronous futures, we're done.
if (pendingList == null) if (pendingList == null) {
return SynchronousFuture<Map<Type, dynamic>>(output); return SynchronousFuture<Map<Type, dynamic>>(output);
}
// Some of delegate.load() values were asynchronous futures. Wait for them. // Some of delegate.load() values were asynchronous futures. Wait for them.
return Future.wait<dynamic>(pendingList.map<Future<dynamic>>((_Pending p) => p.futureValue)) return Future.wait<dynamic>(pendingList.map<Future<dynamic>>((_Pending p) => p.futureValue))
...@@ -381,8 +382,9 @@ class Localizations extends StatefulWidget { ...@@ -381,8 +382,9 @@ class Localizations extends StatefulWidget {
Widget? child, Widget? child,
}) { }) {
final List<LocalizationsDelegate<dynamic>> mergedDelegates = Localizations._delegatesOf(context); final List<LocalizationsDelegate<dynamic>> mergedDelegates = Localizations._delegatesOf(context);
if (delegates != null) if (delegates != null) {
mergedDelegates.insertAll(0, delegates); mergedDelegates.insertAll(0, delegates);
}
return Localizations( return Localizations(
key: key, key: key,
locale: locale ?? Localizations.localeOf(context), locale: locale ?? Localizations.localeOf(context),
...@@ -496,16 +498,18 @@ class _LocalizationsState extends State<Localizations> { ...@@ -496,16 +498,18 @@ class _LocalizationsState extends State<Localizations> {
} }
bool _anyDelegatesShouldReload(Localizations old) { bool _anyDelegatesShouldReload(Localizations old) {
if (widget.delegates.length != old.delegates.length) if (widget.delegates.length != old.delegates.length) {
return true; return true;
}
final List<LocalizationsDelegate<dynamic>> delegates = widget.delegates.toList(); final List<LocalizationsDelegate<dynamic>> delegates = widget.delegates.toList();
final List<LocalizationsDelegate<dynamic>> oldDelegates = old.delegates.toList(); final List<LocalizationsDelegate<dynamic>> oldDelegates = old.delegates.toList();
for (int i = 0; i < delegates.length; i += 1) { for (int i = 0; i < delegates.length; i += 1) {
final LocalizationsDelegate<dynamic> delegate = delegates[i]; final LocalizationsDelegate<dynamic> delegate = delegates[i];
final LocalizationsDelegate<dynamic> oldDelegate = oldDelegates[i]; final LocalizationsDelegate<dynamic> oldDelegate = oldDelegates[i];
if (delegate.runtimeType != oldDelegate.runtimeType || delegate.shouldReload(oldDelegate)) if (delegate.runtimeType != oldDelegate.runtimeType || delegate.shouldReload(oldDelegate)) {
return true; return true;
} }
}
return false; return false;
} }
...@@ -515,9 +519,10 @@ class _LocalizationsState extends State<Localizations> { ...@@ -515,9 +519,10 @@ class _LocalizationsState extends State<Localizations> {
if (widget.locale != old.locale if (widget.locale != old.locale
|| (widget.delegates == null) || (widget.delegates == null)
|| (widget.delegates != null && old.delegates == null) || (widget.delegates != null && old.delegates == null)
|| (widget.delegates != null && _anyDelegatesShouldReload(old))) || (widget.delegates != null && _anyDelegatesShouldReload(old))) {
load(widget.locale); load(widget.locale);
} }
}
void load(Locale locale) { void load(Locale locale) {
final Iterable<LocalizationsDelegate<dynamic>> delegates = widget.delegates; final Iterable<LocalizationsDelegate<dynamic>> delegates = widget.delegates;
...@@ -568,8 +573,9 @@ class _LocalizationsState extends State<Localizations> { ...@@ -568,8 +573,9 @@ class _LocalizationsState extends State<Localizations> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (_locale == null) if (_locale == null) {
return Container(); return Container();
}
return Semantics( return Semantics(
textDirection: _textDirection, textDirection: _textDirection,
child: _LocalizationsScope( child: _LocalizationsScope(
......
...@@ -436,8 +436,9 @@ class MediaQueryData { ...@@ -436,8 +436,9 @@ class MediaQueryData {
bool removeRight = false, bool removeRight = false,
bool removeBottom = false, bool removeBottom = false,
}) { }) {
if (!(removeLeft || removeTop || removeRight || removeBottom)) if (!(removeLeft || removeTop || removeRight || removeBottom)) {
return this; return this;
}
return copyWith( return copyWith(
padding: padding.copyWith( padding: padding.copyWith(
left: removeLeft ? 0.0 : null, left: removeLeft ? 0.0 : null,
...@@ -473,8 +474,9 @@ class MediaQueryData { ...@@ -473,8 +474,9 @@ class MediaQueryData {
bool removeRight = false, bool removeRight = false,
bool removeBottom = false, bool removeBottom = false,
}) { }) {
if (!(removeLeft || removeTop || removeRight || removeBottom)) if (!(removeLeft || removeTop || removeRight || removeBottom)) {
return this; return this;
}
return copyWith( return copyWith(
viewPadding: viewPadding.copyWith( viewPadding: viewPadding.copyWith(
left: removeLeft ? math.max(0.0, viewPadding.left - viewInsets.left) : null, left: removeLeft ? math.max(0.0, viewPadding.left - viewInsets.left) : null,
...@@ -510,8 +512,9 @@ class MediaQueryData { ...@@ -510,8 +512,9 @@ class MediaQueryData {
bool removeRight = false, bool removeRight = false,
bool removeBottom = false, bool removeBottom = false,
}) { }) {
if (!(removeLeft || removeTop || removeRight || removeBottom)) if (!(removeLeft || removeTop || removeRight || removeBottom)) {
return this; return this;
}
return copyWith( return copyWith(
padding: padding.copyWith( padding: padding.copyWith(
left: removeLeft ? 0.0 : null, left: removeLeft ? 0.0 : null,
...@@ -548,8 +551,9 @@ class MediaQueryData { ...@@ -548,8 +551,9 @@ class MediaQueryData {
assert(subScreen.left >= 0.0 && subScreen.top >= 0.0 && assert(subScreen.left >= 0.0 && subScreen.top >= 0.0 &&
subScreen.right <= size.width && subScreen.bottom <= size.height, subScreen.right <= size.width && subScreen.bottom <= size.height,
"'subScreen' argument cannot be outside the bounds of the screen"); "'subScreen' argument cannot be outside the bounds of the screen");
if (subScreen.size == size && subScreen.topLeft == Offset.zero) if (subScreen.size == size && subScreen.topLeft == Offset.zero) {
return this; return this;
}
final double rightInset = size.width - subScreen.right; final double rightInset = size.width - subScreen.right;
final double bottomInset = size.height - subScreen.bottom; final double bottomInset = size.height - subScreen.bottom;
return copyWith( return copyWith(
...@@ -579,8 +583,9 @@ class MediaQueryData { ...@@ -579,8 +583,9 @@ class MediaQueryData {
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
if (other.runtimeType != runtimeType) if (other.runtimeType != runtimeType) {
return false; return false;
}
return other is MediaQueryData return other is MediaQueryData
&& other.size == size && other.size == size
&& other.devicePixelRatio == devicePixelRatio && other.devicePixelRatio == devicePixelRatio
......
...@@ -238,8 +238,9 @@ class _AnyTapGestureRecognizer extends BaseTapGestureRecognizer { ...@@ -238,8 +238,9 @@ class _AnyTapGestureRecognizer extends BaseTapGestureRecognizer {
@protected @protected
@override @override
bool isPointerAllowed(PointerDownEvent event) { bool isPointerAllowed(PointerDownEvent event) {
if (onAnyTapUp == null) if (onAnyTapUp == null) {
return false; return false;
}
return super.isPointerAllowed(event); return super.isPointerAllowed(event);
} }
......
...@@ -152,11 +152,12 @@ class _ToolbarLayout extends MultiChildLayoutDelegate { ...@@ -152,11 +152,12 @@ class _ToolbarLayout extends MultiChildLayoutDelegate {
// widgets, then align its left or right edge with the adjacent boundary. // widgets, then align its left or right edge with the adjacent boundary.
if (centerMiddle) { if (centerMiddle) {
middleStart = (size.width - middleSize.width) / 2.0; middleStart = (size.width - middleSize.width) / 2.0;
if (middleStart + middleSize.width > size.width - trailingWidth) if (middleStart + middleSize.width > size.width - trailingWidth) {
middleStart = size.width - trailingWidth - middleSize.width; middleStart = size.width - trailingWidth - middleSize.width;
else if (middleStart < middleStartMargin) } else if (middleStart < middleStartMargin) {
middleStart = middleStartMargin; middleStart = middleStartMargin;
} }
}
final double middleX; final double middleX;
switch (textDirection) { switch (textDirection) {
......
...@@ -276,8 +276,9 @@ class _RenderOverflowBar extends RenderBox ...@@ -276,8 +276,9 @@ class _RenderOverflowBar extends RenderBox
double _spacing; double _spacing;
set spacing (double value) { set spacing (double value) {
assert(value != null); assert(value != null);
if (_spacing == value) if (_spacing == value) {
return; return;
}
_spacing = value; _spacing = value;
markNeedsLayout(); markNeedsLayout();
} }
...@@ -285,8 +286,9 @@ class _RenderOverflowBar extends RenderBox ...@@ -285,8 +286,9 @@ class _RenderOverflowBar extends RenderBox
MainAxisAlignment? get alignment => _alignment; MainAxisAlignment? get alignment => _alignment;
MainAxisAlignment? _alignment; MainAxisAlignment? _alignment;
set alignment (MainAxisAlignment? value) { set alignment (MainAxisAlignment? value) {
if (_alignment == value) if (_alignment == value) {
return; return;
}
_alignment = value; _alignment = value;
markNeedsLayout(); markNeedsLayout();
} }
...@@ -295,8 +297,9 @@ class _RenderOverflowBar extends RenderBox ...@@ -295,8 +297,9 @@ class _RenderOverflowBar extends RenderBox
double _overflowSpacing; double _overflowSpacing;
set overflowSpacing (double value) { set overflowSpacing (double value) {
assert(value != null); assert(value != null);
if (_overflowSpacing == value) if (_overflowSpacing == value) {
return; return;
}
_overflowSpacing = value; _overflowSpacing = value;
markNeedsLayout(); markNeedsLayout();
} }
...@@ -305,8 +308,9 @@ class _RenderOverflowBar extends RenderBox ...@@ -305,8 +308,9 @@ class _RenderOverflowBar extends RenderBox
OverflowBarAlignment _overflowAlignment; OverflowBarAlignment _overflowAlignment;
set overflowAlignment (OverflowBarAlignment value) { set overflowAlignment (OverflowBarAlignment value) {
assert(value != null); assert(value != null);
if (_overflowAlignment == value) if (_overflowAlignment == value) {
return; return;
}
_overflowAlignment = value; _overflowAlignment = value;
markNeedsLayout(); markNeedsLayout();
} }
...@@ -315,8 +319,9 @@ class _RenderOverflowBar extends RenderBox ...@@ -315,8 +319,9 @@ class _RenderOverflowBar extends RenderBox
VerticalDirection _overflowDirection; VerticalDirection _overflowDirection;
set overflowDirection (VerticalDirection value) { set overflowDirection (VerticalDirection value) {
assert(value != null); assert(value != null);
if (_overflowDirection == value) if (_overflowDirection == value) {
return; return;
}
_overflowDirection = value; _overflowDirection = value;
markNeedsLayout(); markNeedsLayout();
} }
...@@ -324,8 +329,9 @@ class _RenderOverflowBar extends RenderBox ...@@ -324,8 +329,9 @@ class _RenderOverflowBar extends RenderBox
TextDirection get textDirection => _textDirection; TextDirection get textDirection => _textDirection;
TextDirection _textDirection; TextDirection _textDirection;
set textDirection(TextDirection value) { set textDirection(TextDirection value) {
if (_textDirection == value) if (_textDirection == value) {
return; return;
}
_textDirection = value; _textDirection = value;
markNeedsLayout(); markNeedsLayout();
} }
...@@ -334,8 +340,9 @@ class _RenderOverflowBar extends RenderBox ...@@ -334,8 +340,9 @@ class _RenderOverflowBar extends RenderBox
Clip _clipBehavior = Clip.none; Clip _clipBehavior = Clip.none;
set clipBehavior(Clip value) { set clipBehavior(Clip value) {
assert(value != null); assert(value != null);
if (value == _clipBehavior) if (value == _clipBehavior) {
return; return;
}
_clipBehavior = value; _clipBehavior = value;
markNeedsPaint(); markNeedsPaint();
markNeedsSemanticsUpdate(); markNeedsSemanticsUpdate();
...@@ -343,15 +350,17 @@ class _RenderOverflowBar extends RenderBox ...@@ -343,15 +350,17 @@ class _RenderOverflowBar extends RenderBox
@override @override
void setupParentData(RenderBox child) { void setupParentData(RenderBox child) {
if (child.parentData is! _OverflowBarParentData) if (child.parentData is! _OverflowBarParentData) {
child.parentData = _OverflowBarParentData(); child.parentData = _OverflowBarParentData();
} }
}
@override @override
double computeMinIntrinsicHeight(double width) { double computeMinIntrinsicHeight(double width) {
RenderBox? child = firstChild; RenderBox? child = firstChild;
if (child == null) if (child == null) {
return 0; return 0;
}
double barWidth = 0.0; double barWidth = 0.0;
while (child != null) { while (child != null) {
barWidth += child.getMinIntrinsicWidth(double.infinity); barWidth += child.getMinIntrinsicWidth(double.infinity);
...@@ -380,8 +389,9 @@ class _RenderOverflowBar extends RenderBox ...@@ -380,8 +389,9 @@ class _RenderOverflowBar extends RenderBox
@override @override
double computeMaxIntrinsicHeight(double width) { double computeMaxIntrinsicHeight(double width) {
RenderBox? child = firstChild; RenderBox? child = firstChild;
if (child == null) if (child == null) {
return 0; return 0;
}
double barWidth = 0.0; double barWidth = 0.0;
while (child != null) { while (child != null) {
barWidth += child.getMinIntrinsicWidth(double.infinity); barWidth += child.getMinIntrinsicWidth(double.infinity);
...@@ -410,8 +420,9 @@ class _RenderOverflowBar extends RenderBox ...@@ -410,8 +420,9 @@ class _RenderOverflowBar extends RenderBox
@override @override
double computeMinIntrinsicWidth(double height) { double computeMinIntrinsicWidth(double height) {
RenderBox? child = firstChild; RenderBox? child = firstChild;
if (child == null) if (child == null) {
return 0; return 0;
}
double width = 0.0; double width = 0.0;
while (child != null) { while (child != null) {
width += child.getMinIntrinsicWidth(double.infinity); width += child.getMinIntrinsicWidth(double.infinity);
...@@ -423,8 +434,9 @@ class _RenderOverflowBar extends RenderBox ...@@ -423,8 +434,9 @@ class _RenderOverflowBar extends RenderBox
@override @override
double computeMaxIntrinsicWidth(double height) { double computeMaxIntrinsicWidth(double height) {
RenderBox? child = firstChild; RenderBox? child = firstChild;
if (child == null) if (child == null) {
return 0; return 0;
}
double width = 0.0; double width = 0.0;
while (child != null) { while (child != null) {
width += child.getMaxIntrinsicWidth(double.infinity); width += child.getMaxIntrinsicWidth(double.infinity);
......
...@@ -90,8 +90,9 @@ class OverlayEntry implements Listenable { ...@@ -90,8 +90,9 @@ class OverlayEntry implements Listenable {
bool _opaque; bool _opaque;
set opaque(bool value) { set opaque(bool value) {
assert(!_disposedByOwner); assert(!_disposedByOwner);
if (_opaque == value) if (_opaque == value) {
return; return;
}
_opaque = value; _opaque = value;
_overlay?._didChangeEntryOpacity(); _overlay?._didChangeEntryOpacity();
} }
...@@ -115,8 +116,9 @@ class OverlayEntry implements Listenable { ...@@ -115,8 +116,9 @@ class OverlayEntry implements Listenable {
set maintainState(bool value) { set maintainState(bool value) {
assert(!_disposedByOwner); assert(!_disposedByOwner);
assert(_maintainState != null); assert(_maintainState != null);
if (_maintainState == value) if (_maintainState == value) {
return; return;
}
_maintainState = value; _maintainState = value;
assert(_overlay != null); assert(_overlay != null);
_overlay!._didChangeEntryOpacity(); _overlay!._didChangeEntryOpacity();
...@@ -160,8 +162,9 @@ class OverlayEntry implements Listenable { ...@@ -160,8 +162,9 @@ class OverlayEntry implements Listenable {
assert(!_disposedByOwner); assert(!_disposedByOwner);
final OverlayState overlay = _overlay!; final OverlayState overlay = _overlay!;
_overlay = null; _overlay = null;
if (!overlay.mounted) if (!overlay.mounted) {
return; return;
}
overlay._entries.remove(this); overlay._entries.remove(this);
if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks) { if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks) {
...@@ -381,10 +384,12 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin { ...@@ -381,10 +384,12 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
int _insertionIndex(OverlayEntry? below, OverlayEntry? above) { int _insertionIndex(OverlayEntry? below, OverlayEntry? above) {
assert(above == null || below == null); assert(above == null || below == null);
if (below != null) if (below != null) {
return _entries.indexOf(below); return _entries.indexOf(below);
if (above != null) }
if (above != null) {
return _entries.indexOf(above) + 1; return _entries.indexOf(above) + 1;
}
return _entries.length; return _entries.length;
} }
...@@ -422,8 +427,9 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin { ...@@ -422,8 +427,9 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
entries.every((OverlayEntry entry) => entry._overlay == null), entries.every((OverlayEntry entry) => entry._overlay == null),
'One or more of the specified entries are already present in another Overlay.', 'One or more of the specified entries are already present in another Overlay.',
); );
if (entries.isEmpty) if (entries.isEmpty) {
return; return;
}
for (final OverlayEntry entry in entries) { for (final OverlayEntry entry in entries) {
assert(entry._overlay == null); assert(entry._overlay == null);
entry._overlay = this; entry._overlay = this;
...@@ -477,10 +483,12 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin { ...@@ -477,10 +483,12 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
newEntriesList.every((OverlayEntry entry) => _entries.indexOf(entry) == _entries.lastIndexOf(entry)), newEntriesList.every((OverlayEntry entry) => _entries.indexOf(entry) == _entries.lastIndexOf(entry)),
'One or more of the specified entries are specified multiple times.', 'One or more of the specified entries are specified multiple times.',
); );
if (newEntriesList.isEmpty) if (newEntriesList.isEmpty) {
return; return;
if (listEquals(_entries, newEntriesList)) }
if (listEquals(_entries, newEntriesList)) {
return; return;
}
final LinkedHashSet<OverlayEntry> old = LinkedHashSet<OverlayEntry>.of(_entries); final LinkedHashSet<OverlayEntry> old = LinkedHashSet<OverlayEntry>.of(_entries);
for (final OverlayEntry entry in newEntriesList) { for (final OverlayEntry entry in newEntriesList) {
entry._overlay ??= this; entry._overlay ??= this;
...@@ -515,9 +523,10 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin { ...@@ -515,9 +523,10 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
result = true; result = true;
break; break;
} }
if (candidate.opaque) if (candidate.opaque) {
break; break;
} }
}
return true; return true;
}()); }());
return result; return result;
...@@ -545,8 +554,9 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin { ...@@ -545,8 +554,9 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
key: entry._key, key: entry._key,
entry: entry, entry: entry,
)); ));
if (entry.opaque) if (entry.opaque) {
onstage = false; onstage = false;
}
} else if (entry.maintainState) { } else if (entry.maintainState) {
children.add(_OverlayEntryWidget( children.add(_OverlayEntryWidget(
key: entry._key, key: entry._key,
...@@ -651,15 +661,17 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox ...@@ -651,15 +661,17 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox
@override @override
void setupParentData(RenderBox child) { void setupParentData(RenderBox child) {
if (child.parentData is! StackParentData) if (child.parentData is! StackParentData) {
child.parentData = StackParentData(); child.parentData = StackParentData();
} }
}
Alignment? _resolvedAlignment; Alignment? _resolvedAlignment;
void _resolve() { void _resolve() {
if (_resolvedAlignment != null) if (_resolvedAlignment != null) {
return; return;
}
_resolvedAlignment = AlignmentDirectional.topStart.resolve(textDirection); _resolvedAlignment = AlignmentDirectional.topStart.resolve(textDirection);
} }
...@@ -671,8 +683,9 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox ...@@ -671,8 +683,9 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox
TextDirection get textDirection => _textDirection; TextDirection get textDirection => _textDirection;
TextDirection _textDirection; TextDirection _textDirection;
set textDirection(TextDirection value) { set textDirection(TextDirection value) {
if (_textDirection == value) if (_textDirection == value) {
return; return;
}
_textDirection = value; _textDirection = value;
_markNeedResolution(); _markNeedResolution();
} }
...@@ -813,8 +826,9 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox ...@@ -813,8 +826,9 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox
return child!.hitTest(result, position: transformed); return child!.hitTest(result, position: transformed);
}, },
); );
if (isHit) if (isHit) {
return true; return true;
}
child = childParentData.previousSibling; child = childParentData.previousSibling;
} }
return false; return false;
......
...@@ -202,8 +202,9 @@ class _GlowingOverscrollIndicatorState extends State<GlowingOverscrollIndicator> ...@@ -202,8 +202,9 @@ class _GlowingOverscrollIndicatorState extends State<GlowingOverscrollIndicator>
final Map<bool, bool> _accepted = <bool, bool>{false: true, true: true}; final Map<bool, bool> _accepted = <bool, bool>{false: true, true: true};
bool _handleScrollNotification(ScrollNotification notification) { bool _handleScrollNotification(ScrollNotification notification) {
if (!widget.notificationPredicate(notification)) if (!widget.notificationPredicate(notification)) {
return false; return false;
}
// Update the paint offset with the current scroll position. This makes // Update the paint offset with the current scroll position. This makes
// sure that the glow effect correctly scrolls in line with the current // sure that the glow effect correctly scrolls in line with the current
...@@ -358,8 +359,9 @@ class _GlowController extends ChangeNotifier { ...@@ -358,8 +359,9 @@ class _GlowController extends ChangeNotifier {
Color _color; Color _color;
set color(Color value) { set color(Color value) {
assert(color != null); assert(color != null);
if (color == value) if (color == value) {
return; return;
}
_color = value; _color = value;
notifyListeners(); notifyListeners();
} }
...@@ -368,8 +370,9 @@ class _GlowController extends ChangeNotifier { ...@@ -368,8 +370,9 @@ class _GlowController extends ChangeNotifier {
Axis _axis; Axis _axis;
set axis(Axis value) { set axis(Axis value) {
assert(axis != null); assert(axis != null);
if (axis == value) if (axis == value) {
return; return;
}
_axis = value; _axis = value;
notifyListeners(); notifyListeners();
} }
...@@ -459,13 +462,15 @@ class _GlowController extends ChangeNotifier { ...@@ -459,13 +462,15 @@ class _GlowController extends ChangeNotifier {
} }
void scrollEnd() { void scrollEnd() {
if (_state == _GlowState.pull) if (_state == _GlowState.pull) {
_recede(_recedeTime); _recede(_recedeTime);
} }
}
void _changePhase(AnimationStatus status) { void _changePhase(AnimationStatus status) {
if (status != AnimationStatus.completed) if (status != AnimationStatus.completed) {
return; return;
}
switch (_state) { switch (_state) {
case _GlowState.absorb: case _GlowState.absorb:
_recede(_recedeTime); _recede(_recedeTime);
...@@ -481,8 +486,9 @@ class _GlowController extends ChangeNotifier { ...@@ -481,8 +486,9 @@ class _GlowController extends ChangeNotifier {
} }
void _recede(Duration duration) { void _recede(Duration duration) {
if (_state == _GlowState.recede || _state == _GlowState.idle) if (_state == _GlowState.recede || _state == _GlowState.idle) {
return; return;
}
_pullRecedeTimer?.cancel(); _pullRecedeTimer?.cancel();
_pullRecedeTimer = null; _pullRecedeTimer = null;
_glowOpacityTween.begin = _glowOpacity.value; _glowOpacityTween.begin = _glowOpacity.value;
...@@ -509,8 +515,9 @@ class _GlowController extends ChangeNotifier { ...@@ -509,8 +515,9 @@ class _GlowController extends ChangeNotifier {
} }
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
if (_glowOpacity.value == 0.0) if (_glowOpacity.value == 0.0) {
return; return;
}
final double baseGlowScale = size.width > size.height ? size.height / size.width : 1.0; final double baseGlowScale = size.width > size.height ? size.height / size.width : 1.0;
final double radius = size.width * 3.0 / 2.0; final double radius = size.width * 3.0 / 2.0;
final double height = math.min(size.height, size.width * _widthToHeightFactor); final double height = math.min(size.height, size.width * _widthToHeightFactor);
...@@ -556,8 +563,9 @@ class _GlowingOverscrollIndicatorPainter extends CustomPainter { ...@@ -556,8 +563,9 @@ class _GlowingOverscrollIndicatorPainter extends CustomPainter {
static const double piOver2 = math.pi / 2.0; static const double piOver2 = math.pi / 2.0;
void _paintSide(Canvas canvas, Size size, _GlowController? controller, AxisDirection axisDirection, GrowthDirection growthDirection) { void _paintSide(Canvas canvas, Size size, _GlowController? controller, AxisDirection axisDirection, GrowthDirection growthDirection) {
if (controller == null) if (controller == null) {
return; return;
}
switch (applyGrowthDirectionToAxisDirection(axisDirection, growthDirection)) { switch (applyGrowthDirectionToAxisDirection(axisDirection, growthDirection)) {
case AxisDirection.up: case AxisDirection.up:
controller.paint(canvas, size); controller.paint(canvas, size);
...@@ -690,8 +698,9 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi ...@@ -690,8 +698,9 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi
bool _accepted = true; bool _accepted = true;
bool _handleScrollNotification(ScrollNotification notification) { bool _handleScrollNotification(ScrollNotification notification) {
if (!widget.notificationPredicate(notification)) if (!widget.notificationPredicate(notification)) {
return false; return false;
}
if (notification is OverscrollNotification) { if (notification is OverscrollNotification) {
_lastOverscrollNotification = notification; _lastOverscrollNotification = notification;
...@@ -878,13 +887,15 @@ class _StretchController extends ChangeNotifier { ...@@ -878,13 +887,15 @@ class _StretchController extends ChangeNotifier {
} }
void scrollEnd() { void scrollEnd() {
if (_state == _StretchState.pull) if (_state == _StretchState.pull) {
_recede(_stretchDuration); _recede(_stretchDuration);
} }
}
void _changePhase(AnimationStatus status) { void _changePhase(AnimationStatus status) {
if (status != AnimationStatus.completed) if (status != AnimationStatus.completed) {
return; return;
}
switch (_state) { switch (_state) {
case _StretchState.absorb: case _StretchState.absorb:
_recede(_stretchDuration); _recede(_stretchDuration);
...@@ -900,8 +911,9 @@ class _StretchController extends ChangeNotifier { ...@@ -900,8 +911,9 @@ class _StretchController extends ChangeNotifier {
} }
void _recede(Duration duration) { void _recede(Duration duration) {
if (_state == _StretchState.recede || _state == _StretchState.idle) if (_state == _StretchState.recede || _state == _StretchState.idle) {
return; return;
}
_stretchSizeTween.begin = _stretchSize.value; _stretchSizeTween.begin = _stretchSize.value;
_stretchSizeTween.end = 0.0; _stretchSizeTween.end = 0.0;
_stretchController.duration = duration; _stretchController.duration = duration;
......
...@@ -33,8 +33,9 @@ class _StorageEntryIdentifier { ...@@ -33,8 +33,9 @@ class _StorageEntryIdentifier {
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
if (other.runtimeType != runtimeType) if (other.runtimeType != runtimeType) {
return false; return false;
}
return other is _StorageEntryIdentifier return other is _StorageEntryIdentifier
&& listEquals<PageStorageKey<dynamic>>(other.keys, keys); && listEquals<PageStorageKey<dynamic>>(other.keys, keys);
} }
...@@ -56,8 +57,9 @@ class PageStorageBucket { ...@@ -56,8 +57,9 @@ class PageStorageBucket {
static bool _maybeAddKey(BuildContext context, List<PageStorageKey<dynamic>> keys) { static bool _maybeAddKey(BuildContext context, List<PageStorageKey<dynamic>> keys) {
final Widget widget = context.widget; final Widget widget = context.widget;
final Key? key = widget.key; final Key? key = widget.key;
if (key is PageStorageKey) if (key is PageStorageKey) {
keys.add(key); keys.add(key);
}
return widget is! PageStorage; return widget is! PageStorage;
} }
...@@ -91,10 +93,11 @@ class PageStorageBucket { ...@@ -91,10 +93,11 @@ class PageStorageBucket {
_storage![identifier] = data; _storage![identifier] = data;
} else { } else {
final _StorageEntryIdentifier contextIdentifier = _computeIdentifier(context); final _StorageEntryIdentifier contextIdentifier = _computeIdentifier(context);
if (contextIdentifier.isNotEmpty) if (contextIdentifier.isNotEmpty) {
_storage![contextIdentifier] = data; _storage![contextIdentifier] = data;
} }
} }
}
/// Read given data from into this page storage bucket using the specified /// Read given data from into this page storage bucket using the specified
/// identifier or an identifier computed from the given context. /// identifier or an identifier computed from the given context.
...@@ -105,10 +108,12 @@ class PageStorageBucket { ...@@ -105,10 +108,12 @@ class PageStorageBucket {
/// If an explicit identifier is not provided and no [PageStorageKey]s /// If an explicit identifier is not provided and no [PageStorageKey]s
/// are found, then null is returned. /// are found, then null is returned.
dynamic readState(BuildContext context, { Object? identifier }) { dynamic readState(BuildContext context, { Object? identifier }) {
if (_storage == null) if (_storage == null) {
return null; return null;
if (identifier != null) }
if (identifier != null) {
return _storage![identifier]; return _storage![identifier];
}
final _StorageEntryIdentifier contextIdentifier = _computeIdentifier(context); final _StorageEntryIdentifier contextIdentifier = _computeIdentifier(context);
return contextIdentifier.isNotEmpty ? _storage![contextIdentifier] : null; return contextIdentifier.isNotEmpty ? _storage![contextIdentifier] : null;
} }
......
...@@ -358,13 +358,15 @@ class _PagePosition extends ScrollPositionWithSingleContext implements PageMetri ...@@ -358,13 +358,15 @@ class _PagePosition extends ScrollPositionWithSingleContext implements PageMetri
double get viewportFraction => _viewportFraction; double get viewportFraction => _viewportFraction;
double _viewportFraction; double _viewportFraction;
set viewportFraction(double value) { set viewportFraction(double value) {
if (_viewportFraction == value) if (_viewportFraction == value) {
return; return;
}
final double? oldPage = page; final double? oldPage = page;
_viewportFraction = value; _viewportFraction = value;
if (oldPage != null) if (oldPage != null) {
forcePixels(getPixelsFromPage(oldPage)); forcePixels(getPixelsFromPage(oldPage));
} }
}
// The amount of offset that will be added to [minScrollExtent] and subtracted // The amount of offset that will be added to [minScrollExtent] and subtracted
// from [maxScrollExtent], such that every page will properly snap to the center // from [maxScrollExtent], such that every page will properly snap to the center
...@@ -408,10 +410,11 @@ class _PagePosition extends ScrollPositionWithSingleContext implements PageMetri ...@@ -408,10 +410,11 @@ class _PagePosition extends ScrollPositionWithSingleContext implements PageMetri
void restoreScrollOffset() { void restoreScrollOffset() {
if (!hasPixels) { if (!hasPixels) {
final double? value = PageStorage.of(context.storageContext)?.readState(context.storageContext) as double?; final double? value = PageStorage.of(context.storageContext)?.readState(context.storageContext) as double?;
if (value != null) if (value != null) {
_pageToUseOnStartup = value; _pageToUseOnStartup = value;
} }
} }
}
@override @override
void saveOffset() { void saveOffset() {
...@@ -525,23 +528,26 @@ class PageScrollPhysics extends ScrollPhysics { ...@@ -525,23 +528,26 @@ class PageScrollPhysics extends ScrollPhysics {
} }
double _getPage(ScrollMetrics position) { double _getPage(ScrollMetrics position) {
if (position is _PagePosition) if (position is _PagePosition) {
return position.page!; return position.page!;
}
return position.pixels / position.viewportDimension; return position.pixels / position.viewportDimension;
} }
double _getPixels(ScrollMetrics position, double page) { double _getPixels(ScrollMetrics position, double page) {
if (position is _PagePosition) if (position is _PagePosition) {
return position.getPixelsFromPage(page); return position.getPixelsFromPage(page);
}
return page * position.viewportDimension; return page * position.viewportDimension;
} }
double _getTargetPixels(ScrollMetrics position, Tolerance tolerance, double velocity) { double _getTargetPixels(ScrollMetrics position, Tolerance tolerance, double velocity) {
double page = _getPage(position); double page = _getPage(position);
if (velocity < -tolerance.velocity) if (velocity < -tolerance.velocity) {
page -= 0.5; page -= 0.5;
else if (velocity > tolerance.velocity) } else if (velocity > tolerance.velocity) {
page += 0.5; page += 0.5;
}
return _getPixels(position, page.roundToDouble()); return _getPixels(position, page.roundToDouble());
} }
...@@ -550,12 +556,14 @@ class PageScrollPhysics extends ScrollPhysics { ...@@ -550,12 +556,14 @@ class PageScrollPhysics extends ScrollPhysics {
// If we're out of range and not headed back in range, defer to the parent // If we're out of range and not headed back in range, defer to the parent
// ballistics, which should put us back in range at a page boundary. // ballistics, which should put us back in range at a page boundary.
if ((velocity <= 0.0 && position.pixels <= position.minScrollExtent) || if ((velocity <= 0.0 && position.pixels <= position.minScrollExtent) ||
(velocity >= 0.0 && position.pixels >= position.maxScrollExtent)) (velocity >= 0.0 && position.pixels >= position.maxScrollExtent)) {
return super.createBallisticSimulation(position, velocity); return super.createBallisticSimulation(position, velocity);
}
final Tolerance tolerance = this.tolerance; final Tolerance tolerance = this.tolerance;
final double target = _getTargetPixels(position, tolerance, velocity); final double target = _getTargetPixels(position, tolerance, velocity);
if (target != position.pixels) if (target != position.pixels) {
return ScrollSpringSimulation(spring, position.pixels, target, velocity, tolerance: tolerance); return ScrollSpringSimulation(spring, position.pixels, target, velocity, tolerance: tolerance);
}
return null; return null;
} }
......
...@@ -103,24 +103,27 @@ class _RawKeyboardListenerState extends State<RawKeyboardListener> { ...@@ -103,24 +103,27 @@ class _RawKeyboardListenerState extends State<RawKeyboardListener> {
} }
void _handleFocusChanged() { void _handleFocusChanged() {
if (widget.focusNode.hasFocus) if (widget.focusNode.hasFocus) {
_attachKeyboardIfDetached(); _attachKeyboardIfDetached();
else } else {
_detachKeyboardIfAttached(); _detachKeyboardIfAttached();
} }
}
bool _listening = false; bool _listening = false;
void _attachKeyboardIfDetached() { void _attachKeyboardIfDetached() {
if (_listening) if (_listening) {
return; return;
}
RawKeyboard.instance.addListener(_handleRawKeyEvent); RawKeyboard.instance.addListener(_handleRawKeyEvent);
_listening = true; _listening = true;
} }
void _detachKeyboardIfAttached() { void _detachKeyboardIfAttached() {
if (!_listening) if (!_listening) {
return; return;
}
RawKeyboard.instance.removeListener(_handleRawKeyEvent); RawKeyboard.instance.removeListener(_handleRawKeyEvent);
_listening = false; _listening = false;
} }
......
...@@ -707,8 +707,9 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke ...@@ -707,8 +707,9 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
overlay.insert(_overlayEntry!); overlay.insert(_overlayEntry!);
for (final _ReorderableItemState childItem in _items.values) { for (final _ReorderableItemState childItem in _items.values) {
if (childItem == item || !childItem.mounted) if (childItem == item || !childItem.mounted) {
continue; continue;
}
childItem.updateForGap(_insertIndex!, _dragInfo!.itemExtent, false, _reverse); childItem.updateForGap(_insertIndex!, _dragInfo!.itemExtent, false, _reverse);
} }
return _dragInfo; return _dragInfo;
...@@ -784,8 +785,9 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke ...@@ -784,8 +785,9 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
} }
void _handleScrollableAutoScrolled() { void _handleScrollableAutoScrolled() {
if (_dragInfo == null) if (_dragInfo == null) {
return; return;
}
_dragUpdateItems(); _dragUpdateItems();
// Continue scrolling if the drag is still in progress. // Continue scrolling if the drag is still in progress.
_autoScroller?.startAutoScrollIfNecessary(_dragTargetRect); _autoScroller?.startAutoScrollIfNecessary(_dragTargetRect);
...@@ -800,8 +802,9 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke ...@@ -800,8 +802,9 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
// Find the new index for inserting the item being dragged. // Find the new index for inserting the item being dragged.
int newIndex = _insertIndex!; int newIndex = _insertIndex!;
for (final _ReorderableItemState item in _items.values) { for (final _ReorderableItemState item in _items.values) {
if (item.index == _dragIndex! || !item.mounted) if (item.index == _dragIndex! || !item.mounted) {
continue; continue;
}
Rect geometry = item.targetGeometry(); Rect geometry = item.targetGeometry();
if (!_dragStartTransitionComplete && _dragIndex! <= item.index) { if (!_dragStartTransitionComplete && _dragIndex! <= item.index) {
...@@ -862,8 +865,9 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke ...@@ -862,8 +865,9 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
if (newIndex != _insertIndex) { if (newIndex != _insertIndex) {
_insertIndex = newIndex; _insertIndex = newIndex;
for (final _ReorderableItemState item in _items.values) { for (final _ReorderableItemState item in _items.values) {
if (item.index == _dragIndex! || !item.mounted) if (item.index == _dragIndex! || !item.mounted) {
continue; continue;
}
item.updateForGap(newIndex, gapExtent, true, _reverse); item.updateForGap(newIndex, gapExtent, true, _reverse);
} }
} }
...@@ -1386,8 +1390,9 @@ class _ReorderableItemGlobalKey extends GlobalObjectKey { ...@@ -1386,8 +1390,9 @@ class _ReorderableItemGlobalKey extends GlobalObjectKey {
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
if (other.runtimeType != runtimeType) if (other.runtimeType != runtimeType) {
return false; return false;
}
return other is _ReorderableItemGlobalKey return other is _ReorderableItemGlobalKey
&& other.subKey == subKey && other.subKey == subKey
&& other.index == index && other.index == index
......
...@@ -739,8 +739,9 @@ mixin RestorationMixin<S extends StatefulWidget> on State<S> { ...@@ -739,8 +739,9 @@ mixin RestorationMixin<S extends StatefulWidget> on State<S> {
if (!property.isRegistered) { if (!property.isRegistered) {
property._register(restorationId, this); property._register(restorationId, this);
void listener() { void listener() {
if (bucket == null) if (bucket == null) {
return; return;
}
_updateProperty(property); _updateProperty(property);
} }
property.addListener(listener); property.addListener(listener);
......
...@@ -588,8 +588,9 @@ class _RouterState<T> extends State<Router<T>> with RestorationMixin { ...@@ -588,8 +588,9 @@ class _RouterState<T> extends State<Router<T>> with RestorationMixin {
bool _routeInformationReportingTaskScheduled = false; bool _routeInformationReportingTaskScheduled = false;
void _scheduleRouteInformationReportingTask() { void _scheduleRouteInformationReportingTask() {
if (_routeInformationReportingTaskScheduled || widget.routeInformationProvider == null) if (_routeInformationReportingTaskScheduled || widget.routeInformationProvider == null) {
return; return;
}
assert(_currentIntentionToReport != null); assert(_currentIntentionToReport != null);
_routeInformationReportingTaskScheduled = true; _routeInformationReportingTaskScheduled = true;
SchedulerBinding.instance.addPostFrameCallback(_reportRouteInformation); SchedulerBinding.instance.addPostFrameCallback(_reportRouteInformation);
...@@ -609,8 +610,9 @@ class _RouterState<T> extends State<Router<T>> with RestorationMixin { ...@@ -609,8 +610,9 @@ class _RouterState<T> extends State<Router<T>> with RestorationMixin {
RouteInformation? _retrieveNewRouteInformation() { RouteInformation? _retrieveNewRouteInformation() {
final T? configuration = widget.routerDelegate.currentConfiguration; final T? configuration = widget.routerDelegate.currentConfiguration;
if (configuration == null) if (configuration == null) {
return null; return null;
}
return widget.routeInformationParser?.restoreRouteInformation(configuration); return widget.routeInformationParser?.restoreRouteInformation(configuration);
} }
...@@ -848,8 +850,9 @@ class _CallbackHookProvider<T> { ...@@ -848,8 +850,9 @@ class _CallbackHookProvider<T> {
@protected @protected
@pragma('vm:notify-debugger-on-exception') @pragma('vm:notify-debugger-on-exception')
T invokeCallback(T defaultValue) { T invokeCallback(T defaultValue) {
if (_callbacks.isEmpty) if (_callbacks.isEmpty) {
return defaultValue; return defaultValue;
}
try { try {
return _callbacks.single(); return _callbacks.single();
} catch (exception, stack) { } catch (exception, stack) {
...@@ -917,8 +920,9 @@ abstract class BackButtonDispatcher extends _CallbackHookProvider<Future<bool>> ...@@ -917,8 +920,9 @@ abstract class BackButtonDispatcher extends _CallbackHookProvider<Future<bool>>
Future<bool> notifyNextChild(bool result) { Future<bool> notifyNextChild(bool result) {
// If the previous child handles the callback, we return the result. // If the previous child handles the callback, we return the result.
if (result) if (result) {
return SynchronousFuture<bool>(result); return SynchronousFuture<bool>(result);
}
// If the previous child did not handle the callback, we ask the next // If the previous child did not handle the callback, we ask the next
// child to handle the it. // child to handle the it.
if (childIndex > 0) { if (childIndex > 0) {
...@@ -1015,17 +1019,19 @@ class RootBackButtonDispatcher extends BackButtonDispatcher with WidgetsBindingO ...@@ -1015,17 +1019,19 @@ class RootBackButtonDispatcher extends BackButtonDispatcher with WidgetsBindingO
@override @override
void addCallback(ValueGetter<Future<bool>> callback) { void addCallback(ValueGetter<Future<bool>> callback) {
if (!hasCallbacks) if (!hasCallbacks) {
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
}
super.addCallback(callback); super.addCallback(callback);
} }
@override @override
void removeCallback(ValueGetter<Future<bool>> callback) { void removeCallback(ValueGetter<Future<bool>> callback) {
super.removeCallback(callback); super.removeCallback(callback);
if (!hasCallbacks) if (!hasCallbacks) {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
} }
}
@override @override
Future<bool> didPopRoute() => invokeCallback(Future<bool>.value(false)); Future<bool> didPopRoute() => invokeCallback(Future<bool>.value(false));
...@@ -1080,9 +1086,10 @@ class ChildBackButtonDispatcher extends BackButtonDispatcher { ...@@ -1080,9 +1086,10 @@ class ChildBackButtonDispatcher extends BackButtonDispatcher {
@override @override
void removeCallback(ValueGetter<Future<bool>> callback) { void removeCallback(ValueGetter<Future<bool>> callback) {
super.removeCallback(callback); super.removeCallback(callback);
if (!hasCallbacks) if (!hasCallbacks) {
parent.forget(this); parent.forget(this);
} }
}
} }
/// A convenience widget that registers a callback for when the back button is pressed. /// A convenience widget that registers a callback for when the back button is pressed.
...@@ -1448,8 +1455,9 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid ...@@ -1448,8 +1455,9 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid
RouteInformation _valueInEngine = RouteInformation(location: WidgetsBinding.instance.platformDispatcher.defaultRouteName); RouteInformation _valueInEngine = RouteInformation(location: WidgetsBinding.instance.platformDispatcher.defaultRouteName);
void _platformReportsNewRouteInformation(RouteInformation routeInformation) { void _platformReportsNewRouteInformation(RouteInformation routeInformation) {
if (_value == routeInformation) if (_value == routeInformation) {
return; return;
}
_value = routeInformation; _value = routeInformation;
_valueInEngine = routeInformation; _valueInEngine = routeInformation;
notifyListeners(); notifyListeners();
...@@ -1457,17 +1465,19 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid ...@@ -1457,17 +1465,19 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid
@override @override
void addListener(VoidCallback listener) { void addListener(VoidCallback listener) {
if (!hasListeners) if (!hasListeners) {
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
}
super.addListener(listener); super.addListener(listener);
} }
@override @override
void removeListener(VoidCallback listener) { void removeListener(VoidCallback listener) {
super.removeListener(listener); super.removeListener(listener);
if (!hasListeners) if (!hasListeners) {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
} }
}
@override @override
void dispose() { void dispose() {
...@@ -1475,8 +1485,9 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid ...@@ -1475,8 +1485,9 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid
// will be added and removed in a coherent fashion such that when the object // will be added and removed in a coherent fashion such that when the object
// is no longer being used, there's no listener, and so it will get garbage // is no longer being used, there's no listener, and so it will get garbage
// collected. // collected.
if (hasListeners) if (hasListeners) {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
}
super.dispose(); super.dispose();
} }
...@@ -1513,8 +1524,9 @@ mixin PopNavigatorRouterDelegateMixin<T> on RouterDelegate<T> { ...@@ -1513,8 +1524,9 @@ mixin PopNavigatorRouterDelegateMixin<T> on RouterDelegate<T> {
@override @override
Future<bool> popRoute() { Future<bool> popRoute() {
final NavigatorState? navigator = navigatorKey?.currentState; final NavigatorState? navigator = navigatorKey?.currentState;
if (navigator == null) if (navigator == null) {
return SynchronousFuture<bool>(false); return SynchronousFuture<bool>(false);
}
return navigator.maybePop(); return navigator.maybePop();
} }
} }
......
...@@ -71,8 +71,9 @@ abstract class OverlayRoute<T> extends Route<T> { ...@@ -71,8 +71,9 @@ abstract class OverlayRoute<T> extends Route<T> {
bool didPop(T? result) { bool didPop(T? result) {
final bool returnValue = super.didPop(result); final bool returnValue = super.didPop(result);
assert(returnValue); assert(returnValue);
if (finishedWhenPopped) if (finishedWhenPopped) {
navigator!.finalizeRoute(this); navigator!.finalizeRoute(this);
}
return returnValue; return returnValue;
} }
...@@ -194,13 +195,15 @@ abstract class TransitionRoute<T> extends OverlayRoute<T> { ...@@ -194,13 +195,15 @@ abstract class TransitionRoute<T> extends OverlayRoute<T> {
void _handleStatusChanged(AnimationStatus status) { void _handleStatusChanged(AnimationStatus status) {
switch (status) { switch (status) {
case AnimationStatus.completed: case AnimationStatus.completed:
if (overlayEntries.isNotEmpty) if (overlayEntries.isNotEmpty) {
overlayEntries.first.opaque = opaque; overlayEntries.first.opaque = opaque;
}
break; break;
case AnimationStatus.forward: case AnimationStatus.forward:
case AnimationStatus.reverse: case AnimationStatus.reverse:
if (overlayEntries.isNotEmpty) if (overlayEntries.isNotEmpty) {
overlayEntries.first.opaque = false; overlayEntries.first.opaque = false;
}
break; break;
case AnimationStatus.dismissed: case AnimationStatus.dismissed:
// We might still be an active route if a subclass is controlling the // We might still be an active route if a subclass is controlling the
...@@ -249,8 +252,9 @@ abstract class TransitionRoute<T> extends OverlayRoute<T> { ...@@ -249,8 +252,9 @@ abstract class TransitionRoute<T> extends OverlayRoute<T> {
void didReplace(Route<dynamic>? oldRoute) { void didReplace(Route<dynamic>? oldRoute) {
assert(_controller != null, '$runtimeType.didReplace called before calling install() or after calling dispose().'); assert(_controller != null, '$runtimeType.didReplace called before calling install() or after calling dispose().');
assert(!_transitionCompleter.isCompleted, 'Cannot reuse a $runtimeType after disposing it.'); assert(!_transitionCompleter.isCompleted, 'Cannot reuse a $runtimeType after disposing it.');
if (oldRoute is TransitionRoute) if (oldRoute is TransitionRoute) {
_controller!.value = oldRoute._controller!.value; _controller!.value = oldRoute._controller!.value;
}
super.didReplace(oldRoute); super.didReplace(oldRoute);
} }
...@@ -633,9 +637,10 @@ mixin LocalHistoryRoute<T> on Route<T> { ...@@ -633,9 +637,10 @@ mixin LocalHistoryRoute<T> on Route<T> {
internalStateChanged = _entriesImpliesAppBarDismissal == 0; internalStateChanged = _entriesImpliesAppBarDismissal == 0;
_entriesImpliesAppBarDismissal += 1; _entriesImpliesAppBarDismissal += 1;
} }
if (wasEmpty || internalStateChanged) if (wasEmpty || internalStateChanged) {
changedInternalState(); changedInternalState();
} }
}
/// Remove a local history entry from this route. /// Remove a local history entry from this route.
/// ///
...@@ -669,8 +674,9 @@ mixin LocalHistoryRoute<T> on Route<T> { ...@@ -669,8 +674,9 @@ mixin LocalHistoryRoute<T> on Route<T> {
@override @override
Future<RoutePopDisposition> willPop() async { Future<RoutePopDisposition> willPop() async {
if (willHandlePopInternally) if (willHandlePopInternally) {
return RoutePopDisposition.pop; return RoutePopDisposition.pop;
}
return super.willPop(); return super.willPop();
} }
...@@ -686,8 +692,9 @@ mixin LocalHistoryRoute<T> on Route<T> { ...@@ -686,8 +692,9 @@ mixin LocalHistoryRoute<T> on Route<T> {
_entriesImpliesAppBarDismissal -= 1; _entriesImpliesAppBarDismissal -= 1;
internalStateChanged = _entriesImpliesAppBarDismissal == 0; internalStateChanged = _entriesImpliesAppBarDismissal == 0;
} }
if (_localHistory!.isEmpty || internalStateChanged) if (_localHistory!.isEmpty || internalStateChanged) {
changedInternalState(); changedInternalState();
}
return false; return false;
} }
return super.didPop(result); return super.didPop(result);
...@@ -1387,8 +1394,9 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T ...@@ -1387,8 +1394,9 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
bool get offstage => _offstage; bool get offstage => _offstage;
bool _offstage = false; bool _offstage = false;
set offstage(bool value) { set offstage(bool value) {
if (_offstage == value) if (_offstage == value) {
return; return;
}
setState(() { setState(() {
_offstage = value; _offstage = value;
}); });
...@@ -1433,9 +1441,10 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T ...@@ -1433,9 +1441,10 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
final _ModalScopeState<T>? scope = _scopeKey.currentState; final _ModalScopeState<T>? scope = _scopeKey.currentState;
assert(scope != null); assert(scope != null);
for (final WillPopCallback callback in List<WillPopCallback>.of(_willPopCallbacks)) { for (final WillPopCallback callback in List<WillPopCallback>.of(_willPopCallbacks)) {
if (await callback() != true) if (await callback() != true) {
return RoutePopDisposition.doNotPop; return RoutePopDisposition.doNotPop;
} }
}
return super.willPop(); return super.willPop();
} }
...@@ -1575,9 +1584,10 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T ...@@ -1575,9 +1584,10 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
void changedExternalState() { void changedExternalState() {
super.changedExternalState(); super.changedExternalState();
_modalBarrier.markNeedsBuild(); _modalBarrier.markNeedsBuild();
if (_scopeKey.currentState != null) if (_scopeKey.currentState != null) {
_scopeKey.currentState!._forceRebuildPage(); _scopeKey.currentState!._forceRebuildPage();
} }
}
/// Whether this route can be popped. /// Whether this route can be popped.
/// ///
...@@ -1975,6 +1985,7 @@ class RawDialogRoute<T> extends PopupRoute<T> { ...@@ -1975,6 +1985,7 @@ class RawDialogRoute<T> extends PopupRoute<T> {
@override @override
Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) { Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
if (_transitionBuilder == null) { if (_transitionBuilder == null) {
// Some default transition.
return FadeTransition( return FadeTransition(
opacity: CurvedAnimation( opacity: CurvedAnimation(
parent: animation, parent: animation,
...@@ -1982,7 +1993,7 @@ class RawDialogRoute<T> extends PopupRoute<T> { ...@@ -1982,7 +1993,7 @@ class RawDialogRoute<T> extends PopupRoute<T> {
), ),
child: child, child: child,
); );
} // Some default transition }
return _transitionBuilder!(context, animation, secondaryAnimation, child); return _transitionBuilder!(context, animation, secondaryAnimation, child);
} }
} }
...@@ -2138,9 +2149,10 @@ class FocusTrap extends SingleChildRenderObjectWidget { ...@@ -2138,9 +2149,10 @@ class FocusTrap extends SingleChildRenderObjectWidget {
@override @override
void updateRenderObject(BuildContext context, RenderObject renderObject) { void updateRenderObject(BuildContext context, RenderObject renderObject) {
if (renderObject is _RenderFocusTrap) if (renderObject is _RenderFocusTrap) {
renderObject.focusScopeNode = focusScopeNode; renderObject.focusScopeNode = focusScopeNode;
} }
}
} }
/// Declares a widget subtree which is part of the provided [focusNode]'s focus area /// Declares a widget subtree which is part of the provided [focusNode]'s focus area
...@@ -2170,9 +2182,10 @@ class FocusTrapArea extends SingleChildRenderObjectWidget { ...@@ -2170,9 +2182,10 @@ class FocusTrapArea extends SingleChildRenderObjectWidget {
@override @override
void updateRenderObject(BuildContext context, RenderObject renderObject) { void updateRenderObject(BuildContext context, RenderObject renderObject) {
if (renderObject is _RenderFocusTrapArea) if (renderObject is _RenderFocusTrapArea) {
renderObject.focusNode = focusNode; renderObject.focusNode = focusNode;
} }
}
} }
class _RenderFocusTrapArea extends RenderProxyBox { class _RenderFocusTrapArea extends RenderProxyBox {
...@@ -2191,8 +2204,9 @@ class _RenderFocusTrap extends RenderProxyBoxWithHitTestBehavior { ...@@ -2191,8 +2204,9 @@ class _RenderFocusTrap extends RenderProxyBoxWithHitTestBehavior {
FocusNode? _previousFocus; FocusNode? _previousFocus;
FocusScopeNode get focusScopeNode => _focusScopeNode; FocusScopeNode get focusScopeNode => _focusScopeNode;
set focusScopeNode(FocusScopeNode value) { set focusScopeNode(FocusScopeNode value) {
if (focusScopeNode == value) if (focusScopeNode == value) {
return; return;
}
_focusScopeNode = value; _focusScopeNode = value;
} }
...@@ -2249,12 +2263,14 @@ class _RenderFocusTrap extends RenderProxyBoxWithHitTestBehavior { ...@@ -2249,12 +2263,14 @@ class _RenderFocusTrap extends RenderProxyBoxWithHitTestBehavior {
} }
final BoxHitTestResult? result = cachedResults[entry]; final BoxHitTestResult? result = cachedResults[entry];
final FocusNode? focusNode = _focusScopeNode.focusedChild; final FocusNode? focusNode = _focusScopeNode.focusedChild;
if (focusNode == null || result == null) if (focusNode == null || result == null) {
return; return;
}
final RenderObject? renderObject = focusNode.context?.findRenderObject(); final RenderObject? renderObject = focusNode.context?.findRenderObject();
if (renderObject == null) if (renderObject == null) {
return; return;
}
bool hitCurrentFocus = false; bool hitCurrentFocus = false;
for (final HitTestEntry entry in result.path) { for (final HitTestEntry entry in result.path) {
......
...@@ -96,8 +96,9 @@ class SafeArea extends StatelessWidget { ...@@ -96,8 +96,9 @@ class SafeArea extends StatelessWidget {
final MediaQueryData data = MediaQuery.of(context); final MediaQueryData data = MediaQuery.of(context);
EdgeInsets padding = data.padding; EdgeInsets padding = data.padding;
// Bottom padding has been consumed - i.e. by the keyboard // Bottom padding has been consumed - i.e. by the keyboard
if (maintainBottomViewPadding) if (maintainBottomViewPadding) {
padding = padding.copyWith(bottom: data.viewPadding.bottom); padding = padding.copyWith(bottom: data.viewPadding.bottom);
}
return Padding( return Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(
......
...@@ -382,8 +382,9 @@ class ScrollDragController implements Drag { ...@@ -382,8 +382,9 @@ class ScrollDragController implements Drag {
if (offset == 0.0) { if (offset == 0.0) {
return; return;
} }
if (_reversed) // e.g. an AxisDirection.up scrollable if (_reversed) {
offset = -offset; offset = -offset;
}
delegate.applyUserOffset(offset); delegate.applyUserOffset(offset);
} }
...@@ -394,8 +395,9 @@ class ScrollDragController implements Drag { ...@@ -394,8 +395,9 @@ class ScrollDragController implements Drag {
// the scroll has to move upwards. It's the same reason that update() // the scroll has to move upwards. It's the same reason that update()
// above negates the delta before applying it to the scroll offset. // above negates the delta before applying it to the scroll offset.
double velocity = -details.primaryVelocity!; double velocity = -details.primaryVelocity!;
if (_reversed) // e.g. an AxisDirection.up scrollable if (_reversed) {
velocity = -velocity; velocity = -velocity;
}
_lastDetails = details; _lastDetails = details;
if (_retainMomentum) { if (_retainMomentum) {
...@@ -549,9 +551,10 @@ class BallisticScrollActivity extends ScrollActivity { ...@@ -549,9 +551,10 @@ class BallisticScrollActivity extends ScrollActivity {
} }
void _tick() { void _tick() {
if (!applyMoveTo(_controller.value)) if (!applyMoveTo(_controller.value)) {
delegate.goIdle(); delegate.goIdle();
} }
}
/// Move the position to the given location. /// Move the position to the given location.
/// ///
...@@ -643,9 +646,10 @@ class DrivenScrollActivity extends ScrollActivity { ...@@ -643,9 +646,10 @@ class DrivenScrollActivity extends ScrollActivity {
Future<void> get done => _completer.future; Future<void> get done => _completer.future;
void _tick() { void _tick() {
if (delegate.setPixels(_controller.value) != 0.0) if (delegate.setPixels(_controller.value) != 0.0) {
delegate.goIdle(); delegate.goIdle();
} }
}
void _end() { void _end() {
delegate.goBallistic(velocity); delegate.goBallistic(velocity);
......
...@@ -295,15 +295,17 @@ class _WrappedScrollBehavior implements ScrollBehavior { ...@@ -295,15 +295,17 @@ class _WrappedScrollBehavior implements ScrollBehavior {
@override @override
Widget buildOverscrollIndicator(BuildContext context, Widget child, ScrollableDetails details) { Widget buildOverscrollIndicator(BuildContext context, Widget child, ScrollableDetails details) {
if (overscroll) if (overscroll) {
return delegate.buildOverscrollIndicator(context, child, details); return delegate.buildOverscrollIndicator(context, child, details);
}
return child; return child;
} }
@override @override
Widget buildScrollbar(BuildContext context, Widget child, ScrollableDetails details) { Widget buildScrollbar(BuildContext context, Widget child, ScrollableDetails details) {
if (scrollbars) if (scrollbars) {
return delegate.buildScrollbar(context, child, details); return delegate.buildScrollbar(context, child, details);
}
return child; return child;
} }
......
...@@ -168,9 +168,10 @@ class ScrollController extends ChangeNotifier { ...@@ -168,9 +168,10 @@ class ScrollController extends ChangeNotifier {
/// value was out of range. /// value was out of range.
void jumpTo(double value) { void jumpTo(double value) {
assert(_positions.isNotEmpty, 'ScrollController not attached to any scroll views.'); assert(_positions.isNotEmpty, 'ScrollController not attached to any scroll views.');
for (final ScrollPosition position in List<ScrollPosition>.of(_positions)) for (final ScrollPosition position in List<ScrollPosition>.of(_positions)) {
position.jumpTo(value); position.jumpTo(value);
} }
}
/// Register the given position with this controller. /// Register the given position with this controller.
/// ///
...@@ -194,8 +195,9 @@ class ScrollController extends ChangeNotifier { ...@@ -194,8 +195,9 @@ class ScrollController extends ChangeNotifier {
@override @override
void dispose() { void dispose() {
for (final ScrollPosition position in _positions) for (final ScrollPosition position in _positions) {
position.removeListener(notifyListeners); position.removeListener(notifyListeners);
}
super.dispose(); super.dispose();
} }
...@@ -258,10 +260,12 @@ class ScrollController extends ChangeNotifier { ...@@ -258,10 +260,12 @@ class ScrollController extends ChangeNotifier {
/// method, as in `super.debugFillDescription(description)`. /// method, as in `super.debugFillDescription(description)`.
@mustCallSuper @mustCallSuper
void debugFillDescription(List<String> description) { void debugFillDescription(List<String> description) {
if (debugLabel != null) if (debugLabel != null) {
description.add(debugLabel!); description.add(debugLabel!);
if (initialScrollOffset != 0.0) }
if (initialScrollOffset != 0.0) {
description.add('initialScrollOffset: ${initialScrollOffset.toStringAsFixed(1)}, '); description.add('initialScrollOffset: ${initialScrollOffset.toStringAsFixed(1)}, ');
}
if (_positions.isEmpty) { if (_positions.isEmpty) {
description.add('no clients'); description.add('no clients');
} else if (_positions.length == 1) { } else if (_positions.length == 1) {
...@@ -357,11 +361,13 @@ class TrackingScrollController extends ScrollController { ...@@ -357,11 +361,13 @@ class TrackingScrollController extends ScrollController {
assert(_positionToListener.containsKey(position)); assert(_positionToListener.containsKey(position));
position.removeListener(_positionToListener[position]!); position.removeListener(_positionToListener[position]!);
_positionToListener.remove(position); _positionToListener.remove(position);
if (_lastUpdated == position) if (_lastUpdated == position) {
_lastUpdated = null; _lastUpdated = null;
if (_positionToListener.isEmpty) }
if (_positionToListener.isEmpty) {
_lastUpdatedOffset = null; _lastUpdatedOffset = null;
} }
}
@override @override
void dispose() { void dispose() {
......
...@@ -132,9 +132,10 @@ class ScrollStartNotification extends ScrollNotification { ...@@ -132,9 +132,10 @@ class ScrollStartNotification extends ScrollNotification {
@override @override
void debugFillDescription(List<String> description) { void debugFillDescription(List<String> description) {
super.debugFillDescription(description); super.debugFillDescription(description);
if (dragDetails != null) if (dragDetails != null) {
description.add('$dragDetails'); description.add('$dragDetails');
} }
}
} }
/// A notification that a [Scrollable] widget has changed its scroll position. /// A notification that a [Scrollable] widget has changed its scroll position.
...@@ -173,9 +174,10 @@ class ScrollUpdateNotification extends ScrollNotification { ...@@ -173,9 +174,10 @@ class ScrollUpdateNotification extends ScrollNotification {
void debugFillDescription(List<String> description) { void debugFillDescription(List<String> description) {
super.debugFillDescription(description); super.debugFillDescription(description);
description.add('scrollDelta: $scrollDelta'); description.add('scrollDelta: $scrollDelta');
if (dragDetails != null) if (dragDetails != null) {
description.add('$dragDetails'); description.add('$dragDetails');
} }
}
} }
/// A notification that a [Scrollable] widget has not changed its scroll position /// A notification that a [Scrollable] widget has not changed its scroll position
...@@ -226,9 +228,10 @@ class OverscrollNotification extends ScrollNotification { ...@@ -226,9 +228,10 @@ class OverscrollNotification extends ScrollNotification {
super.debugFillDescription(description); super.debugFillDescription(description);
description.add('overscroll: ${overscroll.toStringAsFixed(1)}'); description.add('overscroll: ${overscroll.toStringAsFixed(1)}');
description.add('velocity: ${velocity.toStringAsFixed(1)}'); description.add('velocity: ${velocity.toStringAsFixed(1)}');
if (dragDetails != null) if (dragDetails != null) {
description.add('$dragDetails'); description.add('$dragDetails');
} }
}
} }
/// A notification that a [Scrollable] widget has stopped scrolling. /// A notification that a [Scrollable] widget has stopped scrolling.
...@@ -261,9 +264,10 @@ class ScrollEndNotification extends ScrollNotification { ...@@ -261,9 +264,10 @@ class ScrollEndNotification extends ScrollNotification {
@override @override
void debugFillDescription(List<String> description) { void debugFillDescription(List<String> description) {
super.debugFillDescription(description); super.debugFillDescription(description);
if (dragDetails != null) if (dragDetails != null) {
description.add('$dragDetails'); description.add('$dragDetails');
} }
}
} }
/// A notification that the user has changed the direction in which they are /// A notification that the user has changed the direction in which they are
......
...@@ -124,14 +124,16 @@ class ScrollNotificationObserverState extends State<ScrollNotificationObserver> ...@@ -124,14 +124,16 @@ class ScrollNotificationObserverState extends State<ScrollNotificationObserver>
void _notifyListeners(ScrollNotification notification) { void _notifyListeners(ScrollNotification notification) {
assert(_debugAssertNotDisposed()); assert(_debugAssertNotDisposed());
if (_listeners!.isEmpty) if (_listeners!.isEmpty) {
return; return;
}
final List<_ListenerEntry> localListeners = List<_ListenerEntry>.of(_listeners!); final List<_ListenerEntry> localListeners = List<_ListenerEntry>.of(_listeners!);
for (final _ListenerEntry entry in localListeners) { for (final _ListenerEntry entry in localListeners) {
try { try {
if (entry.list != null) if (entry.list != null) {
entry.listener(notification); entry.listener(notification);
}
} catch (exception, stack) { } catch (exception, stack) {
FlutterError.reportError(FlutterErrorDetails( FlutterError.reportError(FlutterErrorDetails(
exception: exception, exception: exception,
......
...@@ -158,8 +158,9 @@ class ScrollPhysics { ...@@ -158,8 +158,9 @@ class ScrollPhysics {
/// reference to it to use later, as the values may update, may not update, or /// reference to it to use later, as the values may update, may not update, or
/// may update to reflect an entirely unrelated scrollable. /// may update to reflect an entirely unrelated scrollable.
double applyPhysicsToUserOffset(ScrollMetrics position, double offset) { double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
if (parent == null) if (parent == null) {
return offset; return offset;
}
return parent!.applyPhysicsToUserOffset(position, offset); return parent!.applyPhysicsToUserOffset(position, offset);
} }
...@@ -173,8 +174,9 @@ class ScrollPhysics { ...@@ -173,8 +174,9 @@ class ScrollPhysics {
/// reference to it to use later, as the values may update, may not update, or /// reference to it to use later, as the values may update, may not update, or
/// may update to reflect an entirely unrelated scrollable. /// may update to reflect an entirely unrelated scrollable.
bool shouldAcceptUserOffset(ScrollMetrics position) { bool shouldAcceptUserOffset(ScrollMetrics position) {
if (parent == null) if (parent == null) {
return position.pixels != 0.0 || position.minScrollExtent != position.maxScrollExtent; return position.pixels != 0.0 || position.minScrollExtent != position.maxScrollExtent;
}
return parent!.shouldAcceptUserOffset(position); return parent!.shouldAcceptUserOffset(position);
} }
...@@ -265,8 +267,9 @@ class ScrollPhysics { ...@@ -265,8 +267,9 @@ class ScrollPhysics {
/// scrolling back from being overscrolled, if for some reason the position /// scrolling back from being overscrolled, if for some reason the position
/// ends up overscrolled. /// ends up overscrolled.
double applyBoundaryConditions(ScrollMetrics position, double value) { double applyBoundaryConditions(ScrollMetrics position, double value) {
if (parent == null) if (parent == null) {
return 0.0; return 0.0;
}
return parent!.applyBoundaryConditions(position, value); return parent!.applyBoundaryConditions(position, value);
} }
...@@ -320,8 +323,9 @@ class ScrollPhysics { ...@@ -320,8 +323,9 @@ class ScrollPhysics {
required bool isScrolling, required bool isScrolling,
required double velocity, required double velocity,
}) { }) {
if (parent == null) if (parent == null) {
return newPosition.pixels; return newPosition.pixels;
}
return parent!.adjustPositionForNewDimensions(oldPosition: oldPosition, newPosition: newPosition, isScrolling: isScrolling, velocity: velocity); return parent!.adjustPositionForNewDimensions(oldPosition: oldPosition, newPosition: newPosition, isScrolling: isScrolling, velocity: velocity);
} }
...@@ -338,8 +342,9 @@ class ScrollPhysics { ...@@ -338,8 +342,9 @@ class ScrollPhysics {
/// reference to it to use later, as the values may update, may not update, or /// reference to it to use later, as the values may update, may not update, or
/// may update to reflect an entirely unrelated scrollable. /// may update to reflect an entirely unrelated scrollable.
Simulation? createBallisticSimulation(ScrollMetrics position, double velocity) { Simulation? createBallisticSimulation(ScrollMetrics position, double velocity) {
if (parent == null) if (parent == null) {
return null; return null;
}
return parent!.createBallisticSimulation(position, velocity); return parent!.createBallisticSimulation(position, velocity);
} }
...@@ -397,8 +402,9 @@ class ScrollPhysics { ...@@ -397,8 +402,9 @@ class ScrollPhysics {
/// ///
/// By default, physics for platforms other than iOS doesn't carry momentum. /// By default, physics for platforms other than iOS doesn't carry momentum.
double carriedMomentum(double existingVelocity) { double carriedMomentum(double existingVelocity) {
if (parent == null) if (parent == null) {
return 0.0; return 0.0;
}
return parent!.carriedMomentum(existingVelocity); return parent!.carriedMomentum(existingVelocity);
} }
...@@ -419,8 +425,9 @@ class ScrollPhysics { ...@@ -419,8 +425,9 @@ class ScrollPhysics {
@override @override
String toString() { String toString() {
if (parent == null) if (parent == null) {
return objectRuntimeType(this, 'ScrollPhysics'); return objectRuntimeType(this, 'ScrollPhysics');
}
return '${objectRuntimeType(this, 'ScrollPhysics')} -> $parent'; return '${objectRuntimeType(this, 'ScrollPhysics')} -> $parent';
} }
} }
...@@ -609,8 +616,9 @@ class BouncingScrollPhysics extends ScrollPhysics { ...@@ -609,8 +616,9 @@ class BouncingScrollPhysics extends ScrollPhysics {
assert(offset != 0.0); assert(offset != 0.0);
assert(position.minScrollExtent <= position.maxScrollExtent); assert(position.minScrollExtent <= position.maxScrollExtent);
if (!position.outOfRange) if (!position.outOfRange) {
return offset; return offset;
}
final double overscrollPastStart = math.max(position.minScrollExtent - position.pixels, 0.0); final double overscrollPastStart = math.max(position.minScrollExtent - position.pixels, 0.0);
final double overscrollPastEnd = math.max(position.pixels - position.maxScrollExtent, 0.0); final double overscrollPastEnd = math.max(position.pixels - position.maxScrollExtent, 0.0);
...@@ -632,8 +640,9 @@ class BouncingScrollPhysics extends ScrollPhysics { ...@@ -632,8 +640,9 @@ class BouncingScrollPhysics extends ScrollPhysics {
double total = 0.0; double total = 0.0;
if (extentOutside > 0) { if (extentOutside > 0) {
final double deltaToLimit = extentOutside / gamma; final double deltaToLimit = extentOutside / gamma;
if (absDelta < deltaToLimit) if (absDelta < deltaToLimit) {
return absDelta * gamma; return absDelta * gamma;
}
total += extentOutside; total += extentOutside;
absDelta -= deltaToLimit; absDelta -= deltaToLimit;
} }
...@@ -734,14 +743,22 @@ class ClampingScrollPhysics extends ScrollPhysics { ...@@ -734,14 +743,22 @@ class ClampingScrollPhysics extends ScrollPhysics {
} }
return true; return true;
}()); }());
if (value < position.pixels && position.pixels <= position.minScrollExtent) // underscroll if (value < position.pixels && position.pixels <= position.minScrollExtent) {
// Underscroll.
return value - position.pixels; return value - position.pixels;
if (position.maxScrollExtent <= position.pixels && position.pixels < value) // overscroll }
if (position.maxScrollExtent <= position.pixels && position.pixels < value) {
// Overscroll.
return value - position.pixels; return value - position.pixels;
if (value < position.minScrollExtent && position.minScrollExtent < position.pixels) // hit top edge }
if (value < position.minScrollExtent && position.minScrollExtent < position.pixels) {
// Hit top edge.
return value - position.minScrollExtent; return value - position.minScrollExtent;
if (position.pixels < position.maxScrollExtent && position.maxScrollExtent < value) // hit bottom edge }
if (position.pixels < position.maxScrollExtent && position.maxScrollExtent < value) {
// Hit bottom edge.
return value - position.maxScrollExtent; return value - position.maxScrollExtent;
}
return 0.0; return 0.0;
} }
...@@ -750,10 +767,12 @@ class ClampingScrollPhysics extends ScrollPhysics { ...@@ -750,10 +767,12 @@ class ClampingScrollPhysics extends ScrollPhysics {
final Tolerance tolerance = this.tolerance; final Tolerance tolerance = this.tolerance;
if (position.outOfRange) { if (position.outOfRange) {
double? end; double? end;
if (position.pixels > position.maxScrollExtent) if (position.pixels > position.maxScrollExtent) {
end = position.maxScrollExtent; end = position.maxScrollExtent;
if (position.pixels < position.minScrollExtent) }
if (position.pixels < position.minScrollExtent) {
end = position.minScrollExtent; end = position.minScrollExtent;
}
assert(end != null); assert(end != null);
return ScrollSpringSimulation( return ScrollSpringSimulation(
spring, spring,
...@@ -763,12 +782,15 @@ class ClampingScrollPhysics extends ScrollPhysics { ...@@ -763,12 +782,15 @@ class ClampingScrollPhysics extends ScrollPhysics {
tolerance: tolerance, tolerance: tolerance,
); );
} }
if (velocity.abs() < tolerance.velocity) if (velocity.abs() < tolerance.velocity) {
return null; return null;
if (velocity > 0.0 && position.pixels >= position.maxScrollExtent) }
if (velocity > 0.0 && position.pixels >= position.maxScrollExtent) {
return null; return null;
if (velocity < 0.0 && position.pixels <= position.minScrollExtent) }
if (velocity < 0.0 && position.pixels <= position.minScrollExtent) {
return null; return null;
}
return ClampingScrollSimulation( return ClampingScrollSimulation(
position: position.pixels, position: position.pixels,
velocity: velocity, velocity: velocity,
......
...@@ -102,11 +102,13 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { ...@@ -102,11 +102,13 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
assert(context != null), assert(context != null),
assert(context.vsync != null), assert(context.vsync != null),
assert(keepScrollOffset != null) { assert(keepScrollOffset != null) {
if (oldPosition != null) if (oldPosition != null) {
absorb(oldPosition); absorb(oldPosition);
if (keepScrollOffset) }
if (keepScrollOffset) {
restoreScrollOffset(); restoreScrollOffset();
} }
}
/// How the scroll position should respond to user input. /// How the scroll position should respond to user input.
/// ///
...@@ -233,8 +235,9 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { ...@@ -233,8 +235,9 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
assert(other.activity != null); assert(other.activity != null);
_activity = other.activity; _activity = other.activity;
other._activity = null; other._activity = null;
if (other.runtimeType != runtimeType) if (other.runtimeType != runtimeType) {
activity!.resetActivity(); activity!.resetActivity();
}
context.setIgnorePointer(activity!.shouldIgnorePointer); context.setIgnorePointer(activity!.shouldIgnorePointer);
isScrollingNotifier.value = activity!.isScrolling; isScrollingNotifier.value = activity!.isScrolling;
} }
...@@ -422,10 +425,11 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { ...@@ -422,10 +425,11 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
void restoreScrollOffset() { void restoreScrollOffset() {
if (!hasPixels) { if (!hasPixels) {
final double? value = PageStorage.of(context.storageContext)?.readState(context.storageContext) as double?; final double? value = PageStorage.of(context.storageContext)?.readState(context.storageContext) as double?;
if (value != null) if (value != null) {
correctPixels(value); correctPixels(value);
} }
} }
}
/// Called by [context] to restore the scroll offset to the provided value. /// Called by [context] to restore the scroll offset to the provided value.
/// ///
...@@ -661,13 +665,16 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { ...@@ -661,13 +665,16 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
} }
final Set<SemanticsAction> actions = <SemanticsAction>{}; final Set<SemanticsAction> actions = <SemanticsAction>{};
if (pixels > minScrollExtent) if (pixels > minScrollExtent) {
actions.add(backward); actions.add(backward);
if (pixels < maxScrollExtent) }
if (pixels < maxScrollExtent) {
actions.add(forward); actions.add(forward);
}
if (setEquals<SemanticsAction>(actions, _semanticActions)) if (setEquals<SemanticsAction>(actions, _semanticActions)) {
return; return;
}
_semanticActions = actions; _semanticActions = actions;
context.setSemanticsActions(_semanticActions!); context.setSemanticsActions(_semanticActions!);
...@@ -726,8 +733,9 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { ...@@ -726,8 +733,9 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
break; break;
} }
if (target == pixels) if (target == pixels) {
return Future<void>.value(); return Future<void>.value();
}
if (duration == Duration.zero) { if (duration == Duration.zero) {
jumpTo(target); jumpTo(target);
...@@ -823,8 +831,9 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { ...@@ -823,8 +831,9 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
assert(to != null); assert(to != null);
assert(clamp != null); assert(clamp != null);
if (clamp!) if (clamp!) {
to = clampDouble(to, minScrollExtent, maxScrollExtent); to = clampDouble(to, minScrollExtent, maxScrollExtent);
}
return super.moveTo(to, duration: duration, curve: curve); return super.moveTo(to, duration: duration, curve: curve);
} }
...@@ -866,26 +875,31 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { ...@@ -866,26 +875,31 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
/// method might return null, since it means the caller does not have to /// method might return null, since it means the caller does not have to
/// explicitly null-check the argument. /// explicitly null-check the argument.
void beginActivity(ScrollActivity? newActivity) { void beginActivity(ScrollActivity? newActivity) {
if (newActivity == null) if (newActivity == null) {
return; return;
}
bool wasScrolling, oldIgnorePointer; bool wasScrolling, oldIgnorePointer;
if (_activity != null) { if (_activity != null) {
oldIgnorePointer = _activity!.shouldIgnorePointer; oldIgnorePointer = _activity!.shouldIgnorePointer;
wasScrolling = _activity!.isScrolling; wasScrolling = _activity!.isScrolling;
if (wasScrolling && !newActivity.isScrolling) if (wasScrolling && !newActivity.isScrolling) {
didEndScroll(); // notifies and then saves the scroll offset // Notifies and then saves the scroll offset.
didEndScroll();
}
_activity!.dispose(); _activity!.dispose();
} else { } else {
oldIgnorePointer = false; oldIgnorePointer = false;
wasScrolling = false; wasScrolling = false;
} }
_activity = newActivity; _activity = newActivity;
if (oldIgnorePointer != activity!.shouldIgnorePointer) if (oldIgnorePointer != activity!.shouldIgnorePointer) {
context.setIgnorePointer(activity!.shouldIgnorePointer); context.setIgnorePointer(activity!.shouldIgnorePointer);
}
isScrollingNotifier.value = activity!.isScrolling; isScrollingNotifier.value = activity!.isScrolling;
if (!wasScrolling && _activity!.isScrolling) if (!wasScrolling && _activity!.isScrolling) {
didStartScroll(); didStartScroll();
} }
}
// NOTIFICATION DISPATCH // NOTIFICATION DISPATCH
...@@ -906,9 +920,10 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { ...@@ -906,9 +920,10 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
void didEndScroll() { void didEndScroll() {
activity!.dispatchScrollEndNotification(copyWith(), context.notificationContext!); activity!.dispatchScrollEndNotification(copyWith(), context.notificationContext!);
saveOffset(); saveOffset();
if (keepScrollOffset) if (keepScrollOffset) {
saveScrollOffset(); saveScrollOffset();
} }
}
/// Called by [setPixels] to report overscroll when an attempt is made to /// Called by [setPixels] to report overscroll when an attempt is made to
/// change the [pixels] position. Overscroll is the amount of change that was /// change the [pixels] position. Overscroll is the amount of change that was
...@@ -930,9 +945,10 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { ...@@ -930,9 +945,10 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
assert(SchedulerBinding.instance.schedulerPhase != SchedulerPhase.persistentCallbacks); assert(SchedulerBinding.instance.schedulerPhase != SchedulerPhase.persistentCallbacks);
assert(_haveScheduledUpdateNotification); assert(_haveScheduledUpdateNotification);
_haveScheduledUpdateNotification = false; _haveScheduledUpdateNotification = false;
if (context.notificationContext != null) if (context.notificationContext != null) {
ScrollMetricsNotification(metrics: copyWith(), context: context.notificationContext!).dispatch(context.notificationContext); ScrollMetricsNotification(metrics: copyWith(), context: context.notificationContext!).dispatch(context.notificationContext);
} }
}
/// Provides a heuristic to determine if expensive frame-bound tasks should be /// Provides a heuristic to determine if expensive frame-bound tasks should be
/// deferred. /// deferred.
...@@ -971,8 +987,9 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics { ...@@ -971,8 +987,9 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
@override @override
void debugFillDescription(List<String> description) { void debugFillDescription(List<String> description) {
if (debugLabel != null) if (debugLabel != null) {
description.add(debugLabel!); description.add(debugLabel!);
}
super.debugFillDescription(description); super.debugFillDescription(description);
description.add('range: ${_minScrollExtent?.toStringAsFixed(1)}..${_maxScrollExtent?.toStringAsFixed(1)}'); description.add('range: ${_minScrollExtent?.toStringAsFixed(1)}..${_maxScrollExtent?.toStringAsFixed(1)}');
description.add('viewport: ${_viewportDimension?.toStringAsFixed(1)}'); description.add('viewport: ${_viewportDimension?.toStringAsFixed(1)}');
......
...@@ -56,10 +56,12 @@ class ScrollPositionWithSingleContext extends ScrollPosition implements ScrollAc ...@@ -56,10 +56,12 @@ class ScrollPositionWithSingleContext extends ScrollPosition implements ScrollAc
}) { }) {
// If oldPosition is not null, the superclass will first call absorb(), // If oldPosition is not null, the superclass will first call absorb(),
// which may set _pixels and _activity. // which may set _pixels and _activity.
if (!hasPixels && initialPixels != null) if (!hasPixels && initialPixels != null) {
correctPixels(initialPixels); correctPixels(initialPixels);
if (activity == null) }
if (activity == null) {
goIdle(); goIdle();
}
assert(activity != null); assert(activity != null);
} }
...@@ -102,15 +104,17 @@ class ScrollPositionWithSingleContext extends ScrollPosition implements ScrollAc ...@@ -102,15 +104,17 @@ class ScrollPositionWithSingleContext extends ScrollPosition implements ScrollAc
@override @override
void beginActivity(ScrollActivity? newActivity) { void beginActivity(ScrollActivity? newActivity) {
_heldPreviousVelocity = 0.0; _heldPreviousVelocity = 0.0;
if (newActivity == null) if (newActivity == null) {
return; return;
}
assert(newActivity.delegate == this); assert(newActivity.delegate == this);
super.beginActivity(newActivity); super.beginActivity(newActivity);
_currentDrag?.dispose(); _currentDrag?.dispose();
_currentDrag = null; _currentDrag = null;
if (!activity!.isScrolling) if (!activity!.isScrolling) {
updateUserScrollDirection(ScrollDirection.idle); updateUserScrollDirection(ScrollDirection.idle);
} }
}
@override @override
void applyUserOffset(double delta) { void applyUserOffset(double delta) {
...@@ -154,8 +158,9 @@ class ScrollPositionWithSingleContext extends ScrollPosition implements ScrollAc ...@@ -154,8 +158,9 @@ class ScrollPositionWithSingleContext extends ScrollPosition implements ScrollAc
@visibleForTesting @visibleForTesting
void updateUserScrollDirection(ScrollDirection value) { void updateUserScrollDirection(ScrollDirection value) {
assert(value != null); assert(value != null);
if (userScrollDirection == value) if (userScrollDirection == value) {
return; return;
}
_userScrollDirection = value; _userScrollDirection = value;
didUpdateScrollDirection(value); didUpdateScrollDirection(value);
} }
......
...@@ -656,8 +656,9 @@ abstract class BoxScrollView extends ScrollView { ...@@ -656,8 +656,9 @@ abstract class BoxScrollView extends ScrollView {
} }
} }
if (effectivePadding != null) if (effectivePadding != null) {
sliver = SliverPadding(padding: effectivePadding, sliver: sliver); sliver = SliverPadding(padding: effectivePadding, sliver: sliver);
}
return <Widget>[ sliver ]; return <Widget>[ sliver ];
} }
......
...@@ -107,10 +107,11 @@ class _SelectionContainerState extends State<SelectionContainer> with Selectable ...@@ -107,10 +107,11 @@ class _SelectionContainerState extends State<SelectionContainer> with Selectable
super.initState(); super.initState();
if (!widget._disabled) { if (!widget._disabled) {
widget.delegate!._selectionContainerContext = context; widget.delegate!._selectionContainerContext = context;
if (widget.registrar != null) if (widget.registrar != null) {
registrar = widget.registrar; registrar = widget.registrar;
} }
} }
}
@override @override
void didUpdateWidget(SelectionContainer oldWidget) { void didUpdateWidget(SelectionContainer oldWidget) {
...@@ -180,8 +181,9 @@ class _SelectionContainerState extends State<SelectionContainer> with Selectable ...@@ -180,8 +181,9 @@ class _SelectionContainerState extends State<SelectionContainer> with Selectable
@override @override
SelectionGeometry get value { SelectionGeometry get value {
if (widget._disabled) if (widget._disabled) {
return _disabledGeometry; return _disabledGeometry;
}
return widget.delegate!.value; return widget.delegate!.value;
} }
......
...@@ -285,8 +285,9 @@ class LogicalKeySet extends KeySet<LogicalKeyboardKey> with Diagnosticable ...@@ -285,8 +285,9 @@ class LogicalKeySet extends KeySet<LogicalKeyboardKey> with Diagnosticable
@override @override
bool accepts(RawKeyEvent event, RawKeyboard state) { bool accepts(RawKeyEvent event, RawKeyboard state) {
if (event is! RawKeyDownEvent) if (event is! RawKeyDownEvent) {
return false; return false;
}
final Set<LogicalKeyboardKey> collapsedRequired = LogicalKeyboardKey.collapseSynonyms(keys); final Set<LogicalKeyboardKey> collapsedRequired = LogicalKeyboardKey.collapseSynonyms(keys);
final Set<LogicalKeyboardKey> collapsedPressed = LogicalKeyboardKey.collapseSynonyms(state.keysPressed); final Set<LogicalKeyboardKey> collapsedPressed = LogicalKeyboardKey.collapseSynonyms(state.keysPressed);
final bool keysEqual = collapsedRequired.difference(collapsedPressed).isEmpty final bool keysEqual = collapsedRequired.difference(collapsedPressed).isEmpty
......
...@@ -91,8 +91,9 @@ class _RenderSizeChangedWithCallback extends RenderProxyBox { ...@@ -91,8 +91,9 @@ class _RenderSizeChangedWithCallback extends RenderProxyBox {
super.performLayout(); super.performLayout();
// Don't send the initial notification, or this will be SizeObserver all // Don't send the initial notification, or this will be SizeObserver all
// over again! // over again!
if (_oldSize != null && size != _oldSize) if (_oldSize != null && size != _oldSize) {
onLayoutChangedCallback(); onLayoutChangedCallback();
}
_oldSize = size; _oldSize = size;
} }
} }
...@@ -67,9 +67,10 @@ class _RenderSliverLayoutBuilder extends RenderSliver with RenderObjectWithChild ...@@ -67,9 +67,10 @@ class _RenderSliverLayoutBuilder extends RenderSliver with RenderObjectWithChild
@override @override
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
// This renderObject does not introduce additional offset to child's position. // This renderObject does not introduce additional offset to child's position.
if (child?.geometry?.visible ?? false) if (child?.geometry?.visible ?? false) {
context.paintChild(child!, offset); context.paintChild(child!, offset);
} }
}
@override @override
bool hitTestChildren(SliverHitTestResult result, {required double mainAxisPosition, required double crossAxisPosition}) { bool hitTestChildren(SliverHitTestResult result, {required double mainAxisPosition, required double crossAxisPosition}) {
......
This diff is collapsed.
This diff is collapsed.
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