Unverified Commit 127e6790 authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Revert "Nnbd widgets (#64672)" (#65488)

This reverts commit e682ec71.
parent 9e315985
......@@ -645,7 +645,7 @@ class CupertinoTextField extends StatefulWidget {
}
}
class _CupertinoTextFieldState extends State<CupertinoTextField> with RestorationMixin, AutomaticKeepAliveClientMixin<CupertinoTextField> implements TextSelectionGestureDetectorBuilderDelegate {
class _CupertinoTextFieldState extends State<CupertinoTextField> with RestorationMixin, AutomaticKeepAliveClientMixin implements TextSelectionGestureDetectorBuilderDelegate {
final GlobalKey _clearGlobalKey = GlobalKey();
RestorableTextEditingController _controller;
......
......@@ -196,11 +196,28 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
if (firstChild == null) {
if (!addInitialChild(index: firstIndex, layoutOffset: indexToLayoutOffset(itemExtent, firstIndex))) {
// There are either no children, or we are past the end of all our children.
// If it is the latter, we will need to find the first available child.
double max;
if (firstIndex <= 0) {
if (childManager.childCount != null) {
max = computeMaxScrollOffset(constraints, itemExtent);
// TODO(ianh): null-aware flow analysis flags the next two
// branches as entirely dead code, and it's hard to argue with
// its logic.
} else if (firstIndex <= 0) { // ignore: dead_code
max = 0.0;
} else {
max = computeMaxScrollOffset(constraints, itemExtent);
// We will have to find it manually.
int possibleFirstIndex = firstIndex - 1;
while (
possibleFirstIndex > 0 &&
!addInitialChild(
index: possibleFirstIndex,
layoutOffset: indexToLayoutOffset(itemExtent, possibleFirstIndex),
)
) {
possibleFirstIndex -= 1;
}
max = (possibleFirstIndex + 1) * itemExtent;
}
geometry = SliverGeometry(
scrollExtent: max,
......
......@@ -94,9 +94,6 @@ abstract class ViewportOffset extends ChangeNotifier {
/// the value changes due to [correctBy]).
double get pixels;
/// Whether the [pixels] property is available.
bool get hasPixels;
/// Called when the viewport's extents are established.
///
/// The argument is the dimension of the [RenderViewport] in the main axis
......@@ -248,9 +245,7 @@ abstract class ViewportOffset extends ChangeNotifier {
/// `super.debugFillDescription(description)`.
@mustCallSuper
void debugFillDescription(List<String> description) {
if (hasPixels) {
description.add('offset: ${pixels.toStringAsFixed(1)}');
}
description.add('offset: ${pixels.toStringAsFixed(1)}');
}
}
......@@ -263,9 +258,6 @@ class _FixedViewportOffset extends ViewportOffset {
@override
double get pixels => _pixels;
@override
bool get hasPixels => true;
@override
bool applyViewportDimension(double viewportDimension) => true;
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/rendering.dart';
import 'animated_size.dart';
......@@ -118,15 +120,15 @@ class AnimatedCrossFade extends StatefulWidget {
///
/// All the arguments other than [key] must be non-null.
const AnimatedCrossFade({
Key? key,
required this.firstChild,
required this.secondChild,
Key key,
@required this.firstChild,
@required this.secondChild,
this.firstCurve = Curves.linear,
this.secondCurve = Curves.linear,
this.sizeCurve = Curves.linear,
this.alignment = Alignment.topCenter,
required this.crossFadeState,
required this.duration,
@required this.crossFadeState,
@required this.duration,
this.reverseDuration,
this.layoutBuilder = defaultLayoutBuilder,
}) : assert(firstChild != null),
......@@ -161,7 +163,7 @@ class AnimatedCrossFade extends StatefulWidget {
/// The duration of the whole orchestrated animation when running in reverse.
///
/// If not supplied, this defaults to [duration].
final Duration? reverseDuration;
final Duration reverseDuration;
/// The fade curve of the first child.
///
......@@ -247,9 +249,9 @@ class AnimatedCrossFade extends StatefulWidget {
}
class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProviderStateMixin {
AnimationController? _controller;
late Animation<double> _firstAnimation;
late Animation<double> _secondAnimation;
AnimationController _controller;
Animation<double> _firstAnimation;
Animation<double> _secondAnimation;
@override
void initState() {
......@@ -260,10 +262,10 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid
vsync: this,
);
if (widget.crossFadeState == CrossFadeState.showSecond)
_controller!.value = 1.0;
_controller.value = 1.0;
_firstAnimation = _initAnimation(widget.firstCurve, true);
_secondAnimation = _initAnimation(widget.secondCurve, false);
_controller!.addStatusListener((AnimationStatus status) {
_controller.addStatusListener((AnimationStatus status) {
setState(() {
// Trigger a rebuild because it depends on _isTransitioning, which
// changes its value together with animation status.
......@@ -272,7 +274,7 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid
}
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)
result = result.drive(Tween<double>(begin: 1.0, end: 0.0));
return result;
......@@ -280,7 +282,7 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid
@override
void dispose() {
_controller!.dispose();
_controller.dispose();
super.dispose();
}
......@@ -288,9 +290,9 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid
void didUpdateWidget(AnimatedCrossFade oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.duration != oldWidget.duration)
_controller!.duration = widget.duration;
_controller.duration = widget.duration;
if (widget.reverseDuration != oldWidget.reverseDuration)
_controller!.reverseDuration = widget.reverseDuration;
_controller.reverseDuration = widget.reverseDuration;
if (widget.firstCurve != oldWidget.firstCurve)
_firstAnimation = _initAnimation(widget.firstCurve, true);
if (widget.secondCurve != oldWidget.secondCurve)
......@@ -298,24 +300,24 @@ class _AnimatedCrossFadeState extends State<AnimatedCrossFade> with TickerProvid
if (widget.crossFadeState != oldWidget.crossFadeState) {
switch (widget.crossFadeState) {
case CrossFadeState.showFirst:
_controller!.reverse();
_controller.reverse();
break;
case CrossFadeState.showSecond:
_controller!.forward();
_controller.forward();
break;
}
}
}
/// Whether we're in the middle of cross-fading this frame.
bool get _isTransitioning => _controller!.status == AnimationStatus.forward || _controller!.status == AnimationStatus.reverse;
bool get _isTransitioning => _controller.status == AnimationStatus.forward || _controller.status == AnimationStatus.reverse;
@override
Widget build(BuildContext context) {
const Key kFirstChildKey = ValueKey<CrossFadeState>(CrossFadeState.showFirst);
const Key kSecondChildKey = ValueKey<CrossFadeState>(CrossFadeState.showSecond);
final bool transitioningForwards = _controller!.status == AnimationStatus.completed ||
_controller!.status == AnimationStatus.forward;
final bool transitioningForwards = _controller.status == AnimationStatus.completed ||
_controller.status == AnimationStatus.forward;
Key topKey;
Widget topChild;
Animation<double> topAnimation;
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/animation.dart';
import 'package:flutter/foundation.dart';
......@@ -30,8 +32,8 @@ class _ActiveItem implements Comparable<_ActiveItem> {
: controller = null,
removedItemBuilder = null;
final AnimationController? controller;
final AnimatedListRemovedItemBuilder? removedItemBuilder;
final AnimationController controller;
final AnimatedListRemovedItemBuilder removedItemBuilder;
int itemIndex;
@override
......@@ -269,8 +271,8 @@ class AnimatedList extends StatefulWidget {
/// Creates a scrolling container that animates items when they are inserted
/// or removed.
const AnimatedList({
Key? key,
required this.itemBuilder,
Key key,
@required this.itemBuilder,
this.initialItemCount = 0,
this.scrollDirection = Axis.vertical,
this.reverse = false,
......@@ -337,7 +339,7 @@ class AnimatedList extends StatefulWidget {
/// [ScrollController.keepScrollOffset]). It can be used to read the current
/// scroll position (see [ScrollController.offset]), or change it (see
/// [ScrollController.animateTo]).
final ScrollController? controller;
final ScrollController controller;
/// Whether this is the primary scroll view associated with the parent
/// [PrimaryScrollController].
......@@ -347,7 +349,7 @@ class AnimatedList extends StatefulWidget {
///
/// Defaults to true when [scrollDirection] is [Axis.vertical] and
/// [controller] is null.
final bool? primary;
final bool primary;
/// How the scroll view should respond to user input.
///
......@@ -355,7 +357,7 @@ class AnimatedList extends StatefulWidget {
/// user stops dragging the scroll view.
///
/// Defaults to matching platform conventions.
final ScrollPhysics? physics;
final ScrollPhysics physics;
/// Whether the extent of the scroll view in the [scrollDirection] should be
/// determined by the contents being viewed.
......@@ -374,7 +376,7 @@ class AnimatedList extends StatefulWidget {
final bool shrinkWrap;
/// The amount of space by which to inset the children.
final EdgeInsetsGeometry? padding;
final EdgeInsetsGeometry padding;
/// The state from the closest instance of this class that encloses the given
/// context.
......@@ -385,10 +387,10 @@ class AnimatedList extends StatefulWidget {
/// ```dart
/// AnimatedListState animatedList = AnimatedList.of(context);
/// ```
static AnimatedListState? of(BuildContext context, { bool nullOk = false }) {
static AnimatedListState of(BuildContext context, { bool nullOk = false }) {
assert(context != null);
assert(nullOk != null);
final AnimatedListState? result = context.findAncestorStateOfType<AnimatedListState>();
final AnimatedListState result = context.findAncestorStateOfType<AnimatedListState>();
if (nullOk || result != null)
return result;
throw FlutterError.fromParts(<DiagnosticsNode>[
......@@ -442,7 +444,7 @@ class AnimatedListState extends State<AnimatedList> with TickerProviderStateMixi
/// it increases the length of the list by one and shifts all items at or
/// after [index] towards the end of the list.
void insertItem(int index, { Duration duration = _kDuration }) {
_sliverAnimatedListKey.currentState!.insertItem(index, duration: duration);
_sliverAnimatedListKey.currentState.insertItem(index, duration: duration);
}
/// Remove the item at [index] and start an animation that will be passed
......@@ -457,7 +459,7 @@ class AnimatedListState extends State<AnimatedList> with TickerProviderStateMixi
/// it decreases the length of the list by one and shifts all items at or
/// before [index] towards the beginning of the list.
void removeItem(int index, AnimatedListRemovedItemBuilder builder, { Duration duration = _kDuration }) {
_sliverAnimatedListKey.currentState!.removeItem(index, builder, duration: duration);
_sliverAnimatedListKey.currentState.removeItem(index, builder, duration: duration);
}
@override
......@@ -736,8 +738,8 @@ class AnimatedListState extends State<AnimatedList> with TickerProviderStateMixi
class SliverAnimatedList extends StatefulWidget {
/// Creates a sliver that animates items when they are inserted or removed.
const SliverAnimatedList({
Key? key,
required this.itemBuilder,
Key key,
@required this.itemBuilder,
this.initialItemCount = 0,
}) : assert(itemBuilder != null),
assert(initialItemCount != null && initialItemCount >= 0),
......@@ -773,10 +775,10 @@ class SliverAnimatedList extends StatefulWidget {
/// ```dart
/// SliverAnimatedListState animatedList = SliverAnimatedList.of(context);
/// ```
static SliverAnimatedListState? of(BuildContext context, {bool nullOk = false}) {
static SliverAnimatedListState of(BuildContext context, {bool nullOk = false}) {
assert(context != null);
assert(nullOk != null);
final SliverAnimatedListState? result = context.findAncestorStateOfType<SliverAnimatedListState>();
final SliverAnimatedListState result = context.findAncestorStateOfType<SliverAnimatedListState>();
if (nullOk || result != null)
return result;
throw FlutterError(
......@@ -831,17 +833,17 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi
@override
void dispose() {
for (final _ActiveItem item in _incomingItems.followedBy(_outgoingItems)) {
item.controller!.dispose();
item.controller.dispose();
}
super.dispose();
}
_ActiveItem? _removeActiveItemAt(List<_ActiveItem> items, int itemIndex) {
_ActiveItem _removeActiveItemAt(List<_ActiveItem> items, int itemIndex) {
final int i = binarySearch(items, _ActiveItem.index(itemIndex));
return i == -1 ? null : items.removeAt(i);
}
_ActiveItem? _activeItemAt(List<_ActiveItem> items, int itemIndex) {
_ActiveItem _activeItemAt(List<_ActiveItem> items, int itemIndex) {
final int i = binarySearch(items, _ActiveItem.index(itemIndex));
return i == -1 ? null : items[i];
}
......@@ -919,7 +921,7 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi
});
controller.forward().then<void>((_) {
_removeActiveItemAt(_incomingItems, incomingItem.itemIndex)!.controller!.dispose();
_removeActiveItemAt(_incomingItems, incomingItem.itemIndex).controller.dispose();
});
}
......@@ -943,7 +945,7 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi
assert(itemIndex >= 0 && itemIndex < _itemsCount);
assert(_activeItemAt(_outgoingItems, itemIndex) == null);
final _ActiveItem? incomingItem = _removeActiveItemAt(_incomingItems, itemIndex);
final _ActiveItem incomingItem = _removeActiveItemAt(_incomingItems, itemIndex);
final AnimationController controller = incomingItem?.controller
?? AnimationController(duration: duration, value: 1.0, vsync: this);
final _ActiveItem outgoingItem = _ActiveItem.outgoing(controller, itemIndex, builder);
......@@ -954,7 +956,7 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi
});
controller.reverse().then<void>((void value) {
_removeActiveItemAt(_outgoingItems, outgoingItem.itemIndex)!.controller!.dispose();
_removeActiveItemAt(_outgoingItems, outgoingItem.itemIndex).controller.dispose();
// Decrement the incoming and outgoing item indices to account
// for the removal.
......@@ -972,15 +974,15 @@ class SliverAnimatedListState extends State<SliverAnimatedList> with TickerProvi
}
Widget _itemBuilder(BuildContext context, int itemIndex) {
final _ActiveItem? outgoingItem = _activeItemAt(_outgoingItems, itemIndex);
final _ActiveItem outgoingItem = _activeItemAt(_outgoingItems, itemIndex);
if (outgoingItem != null) {
return outgoingItem.removedItemBuilder!(
return outgoingItem.removedItemBuilder(
context,
outgoingItem.controller!.view,
outgoingItem.controller.view,
);
}
final _ActiveItem? incomingItem = _activeItemAt(_incomingItems, itemIndex);
final _ActiveItem incomingItem = _activeItemAt(_incomingItems, itemIndex);
final Animation<double> animation = incomingItem?.controller?.view ?? kAlwaysCompleteAnimation;
return widget.itemBuilder(
context,
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
......@@ -54,13 +56,13 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
///
/// The [curve] and [duration] arguments must not be null.
const AnimatedSize({
Key? key,
Widget? child,
Key key,
Widget child,
this.alignment = Alignment.center,
this.curve = Curves.linear,
required this.duration,
@required this.duration,
this.reverseDuration,
required this.vsync,
@required this.vsync,
}) : super(key: key, child: child);
/// The alignment of the child within the parent when the parent is not yet
......@@ -96,7 +98,7 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
/// size when going in reverse.
///
/// If not specified, defaults to [duration].
final Duration? reverseDuration;
final Duration reverseDuration;
/// The [TickerProvider] for this widget.
final TickerProvider vsync;
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/animation.dart';
import 'package:flutter/foundation.dart';
......@@ -16,10 +18,10 @@ import 'transitions.dart';
// to expose to the public API (like the controller).
class _ChildEntry {
_ChildEntry({
required this.controller,
required this.animation,
required this.transition,
required this.widgetChild,
@required this.controller,
@required this.animation,
@required this.transition,
@required this.widgetChild,
}) : assert(animation != null),
assert(transition != null),
assert(controller != null);
......@@ -61,7 +63,7 @@ typedef AnimatedSwitcherTransitionBuilder = Widget Function(Widget child, Animat
/// The `previousChildren` list is an unmodifiable list, sorted with the oldest
/// at the beginning and the newest at the end. It does not include the
/// `currentChild`.
typedef AnimatedSwitcherLayoutBuilder = Widget Function(Widget? currentChild, List<Widget> previousChildren);
typedef AnimatedSwitcherLayoutBuilder = Widget Function(Widget currentChild, List<Widget> previousChildren);
/// A widget that by default does a cross-fade between a new widget and the
/// widget previously set on the [AnimatedSwitcher] as a child.
......@@ -146,9 +148,9 @@ class AnimatedSwitcher extends StatefulWidget {
/// The [duration], [transitionBuilder], [layoutBuilder], [switchInCurve], and
/// [switchOutCurve] parameters must not be null.
const AnimatedSwitcher({
Key? key,
Key key,
this.child,
required this.duration,
@required this.duration,
this.reverseDuration,
this.switchInCurve = Curves.linear,
this.switchOutCurve = Curves.linear,
......@@ -172,7 +174,7 @@ class AnimatedSwitcher extends StatefulWidget {
/// (see [Widget.canUpdate]).
///
/// To change the kind of transition used, see [transitionBuilder].
final Widget? child;
final Widget child;
/// The duration of the transition from the old [child] value to the new one.
///
......@@ -189,7 +191,7 @@ class AnimatedSwitcher extends StatefulWidget {
/// transitions already in progress.
///
/// If not set, then the value of [duration] is used by default.
final Duration? reverseDuration;
final Duration reverseDuration;
/// The animation curve to use when transitioning in a new [child].
///
......@@ -272,7 +274,7 @@ class AnimatedSwitcher extends StatefulWidget {
/// each other.
///
/// This is an [AnimatedSwitcherLayoutBuilder] function.
static Widget defaultLayoutBuilder(Widget? currentChild, List<Widget> previousChildren) {
static Widget defaultLayoutBuilder(Widget currentChild, List<Widget> previousChildren) {
return Stack(
children: <Widget>[
...previousChildren,
......@@ -291,9 +293,9 @@ class AnimatedSwitcher extends StatefulWidget {
}
class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProviderStateMixin {
_ChildEntry? _currentEntry;
_ChildEntry _currentEntry;
final Set<_ChildEntry> _outgoingEntries = <_ChildEntry>{};
List<Widget>? _outgoingWidgets = const <Widget>[];
List<Widget> _outgoingWidgets = const <Widget>[];
int _childNumber = 0;
@override
......@@ -311,37 +313,37 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider
if (widget.transitionBuilder != oldWidget.transitionBuilder) {
_outgoingEntries.forEach(_updateTransitionForEntry);
if (_currentEntry != null)
_updateTransitionForEntry(_currentEntry!);
_updateTransitionForEntry(_currentEntry);
_markChildWidgetCacheAsDirty();
}
final bool hasNewChild = widget.child != null;
final bool hasOldChild = _currentEntry != null;
if (hasNewChild != hasOldChild ||
hasNewChild && !Widget.canUpdate(widget.child!, _currentEntry!.widgetChild)) {
hasNewChild && !Widget.canUpdate(widget.child, _currentEntry.widgetChild)) {
// Child has changed, fade current entry out and add new entry.
_childNumber += 1;
_addEntryForNewChild(animate: true);
} else if (_currentEntry != null) {
assert(hasOldChild && hasNewChild);
assert(Widget.canUpdate(widget.child!, _currentEntry!.widgetChild));
assert(Widget.canUpdate(widget.child, _currentEntry.widgetChild));
// Child has been updated. Make sure we update the child widget and
// transition in _currentEntry even though we're not going to start a new
// animation, but keep the key from the previous transition so that we
// update the transition instead of replacing it.
_currentEntry!.widgetChild = widget.child!;
_updateTransitionForEntry(_currentEntry!); // uses entry.widgetChild
_currentEntry.widgetChild = widget.child;
_updateTransitionForEntry(_currentEntry); // uses entry.widgetChild
_markChildWidgetCacheAsDirty();
}
}
void _addEntryForNewChild({ required bool animate }) {
void _addEntryForNewChild({ @required bool animate }) {
assert(animate || _currentEntry == null);
if (_currentEntry != null) {
assert(animate);
assert(!_outgoingEntries.contains(_currentEntry));
_outgoingEntries.add(_currentEntry!);
_currentEntry!.controller.reverse();
_outgoingEntries.add(_currentEntry);
_currentEntry.controller.reverse();
_markChildWidgetCacheAsDirty();
_currentEntry = null;
}
......@@ -358,7 +360,7 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider
reverseCurve: widget.switchOutCurve,
);
_currentEntry = _newEntry(
child: widget.child!,
child: widget.child,
controller: controller,
animation: animation,
builder: widget.transitionBuilder,
......@@ -372,10 +374,10 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider
}
_ChildEntry _newEntry({
required Widget child,
required AnimatedSwitcherTransitionBuilder builder,
required AnimationController controller,
required Animation<double> animation,
@required Widget child,
@required AnimatedSwitcherTransitionBuilder builder,
@required AnimationController controller,
@required Animation<double> animation,
}) {
final _ChildEntry entry = _ChildEntry(
widgetChild: child,
......@@ -412,14 +414,14 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider
_outgoingWidgets ??= List<Widget>.unmodifiable(
_outgoingEntries.map<Widget>((_ChildEntry entry) => entry.transition),
);
assert(_outgoingEntries.length == _outgoingWidgets!.length);
assert(_outgoingEntries.isEmpty || _outgoingEntries.last.transition == _outgoingWidgets!.last);
assert(_outgoingEntries.length == _outgoingWidgets.length);
assert(_outgoingEntries.isEmpty || _outgoingEntries.last.transition == _outgoingWidgets.last);
}
@override
void dispose() {
if (_currentEntry != null)
_currentEntry!.controller.dispose();
_currentEntry.controller.dispose();
for (final _ChildEntry entry in _outgoingEntries)
entry.controller.dispose();
super.dispose();
......@@ -428,6 +430,6 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider
@override
Widget build(BuildContext context) {
_rebuildOutgoingWidgetsIfNeeded();
return widget.layoutBuilder(_currentEntry?.transition, _outgoingWidgets!);
return widget.layoutBuilder(_currentEntry?.transition, _outgoingWidgets);
}
}
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
......@@ -13,7 +15,7 @@ import 'framework.dart';
///
/// * [Layer.find], for an example of how this value is retrieved.
/// * [AnnotatedRegionLayer], the layer pushed into the layer tree.
class AnnotatedRegion<T extends Object> extends SingleChildRenderObjectWidget {
class AnnotatedRegion<T> extends SingleChildRenderObjectWidget {
/// Creates a new annotated region to insert [value] into the layer tree.
///
/// Neither [child] nor [value] may be null.
......@@ -21,9 +23,9 @@ class AnnotatedRegion<T extends Object> extends SingleChildRenderObjectWidget {
/// [sized] defaults to true and controls whether the annotated region will
/// clip its child.
const AnnotatedRegion({
Key? key,
required Widget child,
required this.value,
Key key,
@required Widget child,
@required this.value,
this.sized = true,
}) : assert(value != null),
assert(child != null),
......
This diff is collapsed.
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
/// Widgets that handle interaction with asynchronous computations.
///
/// Asynchronous computations are represented by [Future]s and [Stream]s.
......@@ -48,13 +50,13 @@ import 'framework.dart';
/// recent interaction is needed for widget building.
abstract class StreamBuilderBase<T, S> extends StatefulWidget {
/// Creates a [StreamBuilderBase] connected to the specified [stream].
const StreamBuilderBase({ Key? key, this.stream }) : super(key: key);
const StreamBuilderBase({ Key key, this.stream }) : super(key: key);
/// The asynchronous computation to which this builder is currently connected,
/// possibly null. When changed, the current summary is updated using
/// [afterDisconnected], if the previous stream was not null, followed by
/// [afterConnected], if the new stream is not null.
final Stream<T>? stream;
final Stream<T> stream;
/// Returns the initial summary of stream interaction, typically representing
/// the fact that no interaction has happened at all.
......@@ -101,8 +103,8 @@ abstract class StreamBuilderBase<T, S> extends StatefulWidget {
/// State for [StreamBuilderBase].
class _StreamBuilderBaseState<T, S> extends State<StreamBuilderBase<T, S>> {
StreamSubscription<T>? _subscription; // ignore: cancel_subscriptions
late S _summary;
StreamSubscription<T> _subscription;
S _summary;
@override
void initState() {
......@@ -134,7 +136,7 @@ class _StreamBuilderBaseState<T, S> extends State<StreamBuilderBase<T, S>> {
void _subscribe() {
if (widget.stream != null) {
_subscription = widget.stream!.listen((T data) {
_subscription = widget.stream.listen((T data) {
setState(() {
_summary = widget.afterData(_summary, data);
});
......@@ -153,7 +155,7 @@ class _StreamBuilderBaseState<T, S> extends State<StreamBuilderBase<T, S>> {
void _unsubscribe() {
if (_subscription != null) {
_subscription!.cancel();
_subscription.cancel();
_subscription = null;
}
}
......@@ -202,7 +204,7 @@ enum ConnectionState {
/// * [FutureBuilder], which builds itself based on a snapshot from interacting
/// with a [Future].
@immutable
class AsyncSnapshot<T extends Object> {
class AsyncSnapshot<T> {
/// Creates an [AsyncSnapshot] with the specified [connectionState],
/// and optionally either [data] or [error] (but not both).
const AsyncSnapshot._(this.connectionState, this.data, this.error)
......@@ -216,7 +218,7 @@ class AsyncSnapshot<T extends Object> {
const AsyncSnapshot.waiting() : this._(ConnectionState.waiting, null, null);
/// Creates an [AsyncSnapshot] in the specified [state] and with the specified [data].
const AsyncSnapshot.withData(ConnectionState state, T? data) : this._(state, data, null);
const AsyncSnapshot.withData(ConnectionState state, T data) : this._(state, data, null);
/// Creates an [AsyncSnapshot] in the specified [state] and with the specified [error].
const AsyncSnapshot.withError(ConnectionState state, Object error) : this._(state, null, error);
......@@ -233,7 +235,7 @@ class AsyncSnapshot<T extends Object> {
/// If the asynchronous computation has never returned a value, this may be
/// set to an initial data value specified by the relevant widget. See
/// [FutureBuilder.initialData] and [StreamBuilder.initialData].
final T? data;
final T data;
/// Returns latest data received, failing if there is no data.
///
......@@ -241,9 +243,9 @@ class AsyncSnapshot<T extends Object> {
/// nor [hasError].
T get requireData {
if (hasData)
return data!;
return data;
if (hasError)
throw error!;
throw error;
throw StateError('Snapshot has neither data nor error');
}
......@@ -252,7 +254,7 @@ class AsyncSnapshot<T extends Object> {
/// If this is non-null, [hasError] will be true.
///
/// If [data] is not null, this will be null.
final Object? error;
final Object error;
/// Returns a snapshot like this one, but in the specified [state].
///
......@@ -300,7 +302,7 @@ class AsyncSnapshot<T extends Object> {
/// itself based on a snapshot from interacting with a [Stream].
/// * [FutureBuilder], which delegates to an [AsyncWidgetBuilder] to build
/// itself based on a snapshot from interacting with a [Future].
typedef AsyncWidgetBuilder<T extends Object> = Widget Function(BuildContext context, AsyncSnapshot<T> snapshot);
typedef AsyncWidgetBuilder<T> = Widget Function(BuildContext context, AsyncSnapshot<T> snapshot);
/// Widget that builds itself based on the latest snapshot of interaction with
/// a [Stream].
......@@ -465,7 +467,7 @@ typedef AsyncWidgetBuilder<T extends Object> = Widget Function(BuildContext cont
/// * [StreamBuilderBase], which supports widget building based on a computation
/// that spans all interactions made with the stream.
// TODO(ianh): remove unreachable code above once https://github.com/dart-lang/linter/issues/1139 is fixed
class StreamBuilder<T extends Object> extends StreamBuilderBase<T, AsyncSnapshot<T>> {
class StreamBuilder<T> extends StreamBuilderBase<T, AsyncSnapshot<T>> {
/// Creates a new [StreamBuilder] that builds itself based on the latest
/// snapshot of interaction with the specified [stream] and whose build
/// strategy is given by [builder].
......@@ -474,10 +476,10 @@ class StreamBuilder<T extends Object> extends StreamBuilderBase<T, AsyncSnapshot
///
/// The [builder] must not be null.
const StreamBuilder({
Key? key,
Key key,
this.initialData,
Stream<T>? stream,
required this.builder,
Stream<T> stream,
@required this.builder,
}) : assert(builder != null),
super(key: key, stream: stream);
......@@ -495,7 +497,7 @@ class StreamBuilder<T extends Object> extends StreamBuilderBase<T, AsyncSnapshot
/// of whether a value is available on the stream: since streams are
/// asynchronous, no events from the stream can be obtained before the initial
/// build.
final T? initialData;
final T initialData;
@override
AsyncSnapshot<T> initial() => AsyncSnapshot<T>.withData(ConnectionState.none, initialData);
......@@ -660,16 +662,16 @@ class StreamBuilder<T extends Object> extends StreamBuilderBase<T, AsyncSnapshot
/// ```
/// {@end-tool}
// TODO(ianh): remove unreachable code above once https://github.com/dart-lang/sdk/issues/35520 is fixed
class FutureBuilder<T extends Object> extends StatefulWidget {
class FutureBuilder<T> extends StatefulWidget {
/// Creates a widget that builds itself based on the latest snapshot of
/// interaction with a [Future].
///
/// The [builder] must not be null.
const FutureBuilder({
Key? key,
Key key,
this.future,
this.initialData,
required this.builder,
@required this.builder,
}) : assert(builder != null),
super(key: key);
......@@ -678,7 +680,7 @@ class FutureBuilder<T extends Object> extends StatefulWidget {
///
/// If no future has yet completed, including in the case where [future] is
/// null, the data provided to the [builder] will be set to [initialData].
final Future<T>? future;
final Future<T> future;
/// The build strategy currently used by this builder.
///
......@@ -712,19 +714,19 @@ class FutureBuilder<T extends Object> extends StatefulWidget {
/// provided to the [builder] will become null, regardless of [initialData].
/// (The error itself will be available in [AsyncSnapshot.error], and
/// [AsyncSnapshot.hasError] will be true.)
final T? initialData;
final T initialData;
@override
State<FutureBuilder<T>> createState() => _FutureBuilderState<T>();
}
/// State for [FutureBuilder].
class _FutureBuilderState<T extends Object> extends State<FutureBuilder<T>> {
class _FutureBuilderState<T> extends State<FutureBuilder<T>> {
/// An object that identifies the currently active callbacks. Used to avoid
/// calling setState from stale callbacks, e.g. after disposal of this state,
/// or after widget reconfiguration to a new Future.
Object? _activeCallbackIdentity;
late AsyncSnapshot<T> _snapshot;
Object _activeCallbackIdentity;
AsyncSnapshot<T> _snapshot;
@override
void initState() {
......@@ -758,7 +760,7 @@ class _FutureBuilderState<T extends Object> extends State<FutureBuilder<T>> {
if (widget.future != null) {
final Object callbackIdentity = Object();
_activeCallbackIdentity = callbackIdentity;
widget.future!.then<void>((T data) {
widget.future.then<void>((T data) {
if (_activeCallbackIdentity == callbackIdentity) {
setState(() {
_snapshot = AsyncSnapshot<T>.withData(ConnectionState.done, data);
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/services.dart';
import 'framework.dart';
......@@ -150,8 +152,8 @@ class AutofillGroup extends StatefulWidget {
///
/// The [child] argument must not be null.
const AutofillGroup({
Key? key,
required this.child,
Key key,
@required this.child,
this.onDisposeAction = AutofillContextAction.commit,
}) : assert(child != null),
super(key: key);
......@@ -164,8 +166,8 @@ class AutofillGroup extends StatefulWidget {
///
/// * [EditableTextState], where this method is used to retrieve the closest
/// [AutofillGroupState].
static AutofillGroupState? of(BuildContext context) {
final _AutofillScope? scope = context.dependOnInheritedWidgetOfExactType<_AutofillScope>();
static AutofillGroupState of(BuildContext context) {
final _AutofillScope scope = context.dependOnInheritedWidgetOfExactType<_AutofillScope>();
return scope?._scope;
}
......@@ -212,12 +214,12 @@ class AutofillGroupState extends State<AutofillGroup> with AutofillScopeMixin {
bool _isTopmostAutofillGroup = false;
@override
AutofillClient? getAutofillClient(String tag) => _clients[tag];
AutofillClient getAutofillClient(String tag) => _clients[tag];
@override
Iterable<AutofillClient> get autofillClients {
return _clients.values
.where((AutofillClient client) => client.textInputConfiguration.autofillConfiguration != null);
.where((AutofillClient client) => client?.textInputConfiguration?.autofillConfiguration != null);
}
/// Adds the [AutofillClient] to this [AutofillGroup].
......@@ -287,15 +289,15 @@ class AutofillGroupState extends State<AutofillGroup> with AutofillScopeMixin {
class _AutofillScope extends InheritedWidget {
const _AutofillScope({
Key? key,
required Widget child,
AutofillGroupState? autofillScopeState,
Key key,
Widget child,
AutofillGroupState autofillScopeState,
}) : _scope = autofillScopeState,
super(key: key, child: child);
final AutofillGroupState? _scope;
final AutofillGroupState _scope;
AutofillGroup get client => _scope!.widget;
AutofillGroup get client => _scope.widget;
@override
bool updateShouldNotify(_AutofillScope old) => _scope != old._scope;
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:async';
import 'package:flutter/foundation.dart';
......@@ -27,22 +29,22 @@ class AutomaticKeepAlive extends StatefulWidget {
/// Creates a widget that listens to [KeepAliveNotification]s and maintains a
/// [KeepAlive] widget appropriately.
const AutomaticKeepAlive({
Key? key,
Key key,
this.child,
}) : super(key: key);
/// The widget below this widget in the tree.
///
/// {@macro flutter.widgets.child}
final Widget? child;
final Widget child;
@override
_AutomaticKeepAliveState createState() => _AutomaticKeepAliveState();
}
class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
Map<Listenable, VoidCallback>? _handles;
Widget? _child;
Map<Listenable, VoidCallback> _handles;
Widget _child;
bool _keepingAlive = false;
@override
......@@ -60,15 +62,15 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
void _updateChild() {
_child = NotificationListener<KeepAliveNotification>(
onNotification: _addClient,
child: widget.child!,
child: widget.child,
);
}
@override
void dispose() {
if (_handles != null) {
for (final Listenable handle in _handles!.keys)
handle.removeListener(_handles![handle]!);
for (final Listenable handle in _handles.keys)
handle.removeListener(_handles[handle]);
}
super.dispose();
}
......@@ -76,12 +78,12 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
bool _addClient(KeepAliveNotification notification) {
final Listenable handle = notification.handle;
_handles ??= <Listenable, VoidCallback>{};
assert(!_handles!.containsKey(handle));
_handles![handle] = _createCallback(handle);
handle.addListener(_handles![handle]!);
assert(!_handles.containsKey(handle));
_handles[handle] = _createCallback(handle);
handle.addListener(_handles[handle]);
if (!_keepingAlive) {
_keepingAlive = true;
final ParentDataElement<KeepAliveParentDataMixin>? childElement = _getChildElement();
final ParentDataElement<KeepAliveParentDataMixin> childElement = _getChildElement();
if (childElement != null) {
// If the child already exists, update it synchronously.
_updateParentDataOfChild(childElement);
......@@ -89,13 +91,13 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
// If the child doesn't exist yet, we got called during the very first
// build of this subtree. Wait until the end of the frame to update
// the child when the child is guaranteed to be present.
SchedulerBinding.instance!.addPostFrameCallback((Duration timeStamp) {
SchedulerBinding.instance.addPostFrameCallback((Duration timeStamp) {
if (!mounted) {
return;
}
final ParentDataElement<KeepAliveParentDataMixin>? childElement = _getChildElement();
final ParentDataElement<KeepAliveParentDataMixin> childElement = _getChildElement();
assert(childElement != null);
_updateParentDataOfChild(childElement!);
_updateParentDataOfChild(childElement);
});
}
}
......@@ -106,10 +108,10 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
///
/// While this widget is guaranteed to have a child, this may return null if
/// the first build of that child has not completed yet.
ParentDataElement<KeepAliveParentDataMixin>? _getChildElement() {
ParentDataElement<KeepAliveParentDataMixin> _getChildElement() {
assert(mounted);
final Element element = context as Element;
Element? childElement;
Element childElement;
// We use Element.visitChildren rather than context.visitChildElements
// because we might be called during build, and context.visitChildElements
// verifies that it is not called during build. Element.visitChildren does
......@@ -133,7 +135,7 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
childElement = child;
});
assert(childElement == null || childElement is ParentDataElement<KeepAliveParentDataMixin>);
return childElement as ParentDataElement<KeepAliveParentDataMixin>?;
return childElement as ParentDataElement<KeepAliveParentDataMixin>;
}
void _updateParentDataOfChild(ParentDataElement<KeepAliveParentDataMixin> childElement) {
......@@ -153,9 +155,9 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
}
return true;
}());
_handles!.remove(handle);
if (_handles!.isEmpty) {
if (SchedulerBinding.instance!.schedulerPhase.index < SchedulerPhase.persistentCallbacks.index) {
_handles.remove(handle);
if (_handles.isEmpty) {
if (SchedulerBinding.instance.schedulerPhase.index < SchedulerPhase.persistentCallbacks.index) {
// Build/layout haven't started yet so let's just schedule this for
// the next frame.
setState(() { _keepingAlive = false; });
......@@ -211,7 +213,7 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
// avoid it if possible.
_keepingAlive = false;
scheduleMicrotask(() {
if (mounted && _handles!.isEmpty) {
if (mounted && _handles.isEmpty) {
// If mounted is false, we went away as well, so there's nothing to do.
// If _handles is no longer empty, then another client (or the same
// client in a new place) registered itself before we had a chance to
......@@ -231,7 +233,7 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
assert(_child != null);
return KeepAlive(
keepAlive: _keepingAlive,
child: _child!,
child: _child,
);
}
......@@ -244,7 +246,7 @@ class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
'handles',
_handles,
description: _handles != null ?
'${_handles!.length} active client${ _handles!.length == 1 ? "" : "s" }' :
'${_handles.length} active client${ _handles.length == 1 ? "" : "s" }' :
null,
ifNull: 'no notifications ever received',
));
......@@ -328,7 +330,8 @@ class KeepAliveHandle extends ChangeNotifier {
/// with [State] subclasses.
///
/// Subclasses must implement [wantKeepAlive], and their [build] methods must
/// call `super.build` (though the return value should be ignored).
/// call `super.build` (the return value will always return null, and should be
/// ignored).
///
/// Then, whenever [wantKeepAlive]'s value changes (or might change), the
/// subclass should call [updateKeepAlive].
......@@ -342,16 +345,16 @@ class KeepAliveHandle extends ChangeNotifier {
/// * [KeepAliveNotification], the notifications sent by this mixin.
@optionalTypeArgs
mixin AutomaticKeepAliveClientMixin<T extends StatefulWidget> on State<T> {
KeepAliveHandle? _keepAliveHandle;
KeepAliveHandle _keepAliveHandle;
void _ensureKeepAlive() {
assert(_keepAliveHandle == null);
_keepAliveHandle = KeepAliveHandle();
KeepAliveNotification(_keepAliveHandle!).dispatch(context);
KeepAliveNotification(_keepAliveHandle).dispatch(context);
}
void _releaseKeepAlive() {
_keepAliveHandle!.release();
_keepAliveHandle.release();
_keepAliveHandle = null;
}
......@@ -394,18 +397,6 @@ mixin AutomaticKeepAliveClientMixin<T extends StatefulWidget> on State<T> {
Widget build(BuildContext context) {
if (wantKeepAlive && _keepAliveHandle == null)
_ensureKeepAlive();
return const _NullWidget();
}
}
class _NullWidget extends StatelessWidget {
const _NullWidget();
@override
Widget build(BuildContext context) {
throw FlutterError(
'Widgets that mix AutomaticKeepAliveClientMixin into their State must '
'call super.build() but must ignore the return value of the superclass.'
);
return null;
}
}
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math;
import 'package:flutter/foundation.dart';
......@@ -59,10 +61,10 @@ class BannerPainter extends CustomPainter {
/// The [message], [textDirection], [location], and [layoutDirection]
/// arguments must not be null.
BannerPainter({
required this.message,
required this.textDirection,
required this.location,
required this.layoutDirection,
@required this.message,
@required this.textDirection,
@required this.location,
@required this.layoutDirection,
this.color = _kColor,
this.textStyle = _kTextStyle,
}) : assert(message != null),
......@@ -70,7 +72,7 @@ class BannerPainter extends CustomPainter {
assert(location != null),
assert(color != null),
assert(textStyle != null),
super(repaint: PaintingBinding.instance!.systemFonts);
super(repaint: PaintingBinding.instance.systemFonts);
/// The message to show in the banner.
final String message;
......@@ -118,9 +120,9 @@ class BannerPainter extends CustomPainter {
);
bool _prepared = false;
late TextPainter _textPainter;
late Paint _paintShadow;
late Paint _paintBanner;
TextPainter _textPainter;
Paint _paintShadow;
Paint _paintBanner;
void _prepare() {
_paintShadow = _shadow.toPaint();
......@@ -174,6 +176,7 @@ class BannerPainter extends CustomPainter {
case BannerLocation.topStart:
return width;
}
break;
case TextDirection.ltr:
switch (location) {
case BannerLocation.bottomEnd:
......@@ -185,7 +188,9 @@ class BannerPainter extends CustomPainter {
case BannerLocation.topStart:
return 0.0;
}
break;
}
return null;
}
double _translationY(double height) {
......@@ -198,6 +203,7 @@ class BannerPainter extends CustomPainter {
case BannerLocation.topEnd:
return 0.0;
}
return null;
}
double get _rotation {
......@@ -213,6 +219,7 @@ class BannerPainter extends CustomPainter {
case BannerLocation.topStart:
return math.pi / 4.0;
}
break;
case TextDirection.ltr:
switch (location) {
case BannerLocation.bottomStart:
......@@ -222,7 +229,9 @@ class BannerPainter extends CustomPainter {
case BannerLocation.topStart:
return -math.pi / 4.0;
}
break;
}
return null;
}
}
......@@ -240,11 +249,11 @@ class Banner extends StatelessWidget {
///
/// The [message] and [location] arguments must not be null.
const Banner({
Key? key,
Key key,
this.child,
required this.message,
@required this.message,
this.textDirection,
required this.location,
@required this.location,
this.layoutDirection,
this.color = _kColor,
this.textStyle = _kTextStyle,
......@@ -257,7 +266,7 @@ class Banner extends StatelessWidget {
/// The widget to show behind the banner.
///
/// {@macro flutter.widgets.child}
final Widget? child;
final Widget child;
/// The message to show in the banner.
final String message;
......@@ -276,7 +285,7 @@ class Banner extends StatelessWidget {
/// See also:
///
/// * [layoutDirection], which controls the interpretation of the [location].
final TextDirection? textDirection;
final TextDirection textDirection;
/// Where to show the banner (e.g., the upper right corner).
final BannerLocation location;
......@@ -290,7 +299,7 @@ class Banner extends StatelessWidget {
/// See also:
///
/// * [textDirection], which controls the reading direction of the [message].
final TextDirection? layoutDirection;
final TextDirection layoutDirection;
/// The color of the banner.
final Color color;
......@@ -304,9 +313,9 @@ class Banner extends StatelessWidget {
return CustomPaint(
foregroundPainter: BannerPainter(
message: message,
textDirection: textDirection ?? Directionality.of(context)!,
textDirection: textDirection ?? Directionality.of(context),
location: location,
layoutDirection: layoutDirection ?? Directionality.of(context)!,
layoutDirection: layoutDirection ?? Directionality.of(context),
color: color,
textStyle: textStyle,
),
......@@ -322,7 +331,7 @@ class Banner extends StatelessWidget {
properties.add(EnumProperty<BannerLocation>('location', location));
properties.add(EnumProperty<TextDirection>('layoutDirection', layoutDirection, defaultValue: null));
properties.add(ColorProperty('color', color, showName: false));
textStyle.debugFillProperties(properties, prefix: 'text ');
textStyle?.debugFillProperties(properties, prefix: 'text ');
}
}
......@@ -332,8 +341,8 @@ class Banner extends StatelessWidget {
class CheckedModeBanner extends StatelessWidget {
/// Creates a const checked mode banner.
const CheckedModeBanner({
Key? key,
required this.child,
Key key,
@required this.child,
}) : super(key: key);
/// The widget to show behind the banner.
......
This diff is collapsed.
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' show Color;
import 'framework.dart';
......@@ -23,14 +25,14 @@ class BottomNavigationBarItem {
///
/// The argument [icon] should not be null and the argument [title] should not be null when used in a Material Design's [BottomNavigationBar].
const BottomNavigationBarItem({
required this.icon,
@required this.icon,
@Deprecated(
'Use "label" instead, as it allows for an improved text-scaling experience. '
'This feature was deprecated after v1.19.0.'
)
this.title,
this.label,
Widget? activeIcon,
Widget activeIcon,
this.backgroundColor,
}) : activeIcon = activeIcon ?? icon,
assert(label == null || title == null),
......@@ -73,14 +75,14 @@ class BottomNavigationBarItem {
'Use "label" instead, as it allows for an improved text-scaling experience. '
'This feature was deprecated after v1.19.0.'
)
final Widget? title;
final Widget title;
/// The text label for this [BottomNavigationBarItem].
///
/// This will be used to create a [Text] widget to put in the bottom navigation bar,
/// and in Material Design [BottomNavigationBar]s, this will be used to display
/// a tooltip on long press of an item in the [BottomNavigationBar].
final String? label;
final String label;
/// The color of the background radial animation for material [BottomNavigationBar].
///
......@@ -95,5 +97,5 @@ class BottomNavigationBarItem {
///
/// * [Icon.color] and [ImageIcon.color] to control the foreground color of
/// the icons themselves.
final Color? backgroundColor;
final Color backgroundColor;
}
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:ui';
import 'package:flutter/foundation.dart';
......@@ -17,7 +19,7 @@ class ColorFiltered extends SingleChildRenderObjectWidget {
/// Creates a widget that applies a [ColorFilter] to its child.
///
/// The [colorFilter] must not be null.
const ColorFiltered({required this.colorFilter, Widget? child, Key? key})
const ColorFiltered({@required this.colorFilter, Widget child, Key key})
: assert(colorFilter != null),
super(key: key, child: child);
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
/// The minimum dimension of any interactive region according to the Material
/// guidelines.
///
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/rendering.dart';
......@@ -59,10 +61,10 @@ class DecoratedBox extends SingleChildRenderObjectWidget {
/// The [decoration] and [position] arguments must not be null. By default the
/// decoration paints behind the child.
const DecoratedBox({
Key? key,
required this.decoration,
Key key,
@required this.decoration,
this.position = DecorationPosition.background,
Widget? child,
Widget child,
}) : assert(decoration != null),
assert(position != null),
super(key: key, child: child);
......@@ -96,15 +98,19 @@ class DecoratedBox extends SingleChildRenderObjectWidget {
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
String label;
switch (position) {
case DecorationPosition.background:
label = 'bg';
break;
case DecorationPosition.foreground:
label = 'fg';
break;
if (position != null) {
switch (position) {
case DecorationPosition.background:
label = 'bg';
break;
case DecorationPosition.foreground:
label = 'fg';
break;
}
} else {
label = 'decoration';
}
properties.add(EnumProperty<DecorationPosition>('position', position, level: DiagnosticLevel.hidden));
properties.add(EnumProperty<DecorationPosition>('position', position, level: position != null ? DiagnosticLevel.hidden : DiagnosticLevel.info));
properties.add(DiagnosticsProperty<Decoration>(
label,
decoration,
......@@ -257,15 +263,15 @@ class Container extends StatelessWidget {
/// color. To supply a decoration with a color, use `decoration:
/// BoxDecoration(color: color)`.
Container({
Key? key,
Key key,
this.alignment,
this.padding,
this.color,
this.decoration,
this.foregroundDecoration,
double? width,
double? height,
BoxConstraints? constraints,
double width,
double height,
BoxConstraints constraints,
this.margin,
this.transform,
this.child,
......@@ -295,7 +301,7 @@ class Container extends StatelessWidget {
/// will attempt to be as small as possible.
///
/// {@macro flutter.widgets.child}
final Widget? child;
final Widget child;
/// Align the [child] within the container.
///
......@@ -311,14 +317,14 @@ class Container extends StatelessWidget {
/// specify an [AlignmentGeometry].
/// * [AlignmentDirectional], like [Alignment] for specifying alignments
/// relative to text direction.
final AlignmentGeometry? alignment;
final AlignmentGeometry alignment;
/// Empty space to inscribe inside the [decoration]. The [child], if any, is
/// placed inside this padding.
///
/// This padding is in addition to any padding inherent in the [decoration];
/// see [Decoration.padding].
final EdgeInsetsGeometry? padding;
final EdgeInsetsGeometry padding;
/// The color to paint behind the [child].
///
......@@ -329,7 +335,7 @@ class Container extends StatelessWidget {
/// If the [decoration] is used, this property must be null. A background
/// color may still be painted by the [decoration] even if this property is
/// null.
final Color? color;
final Color color;
/// The decoration to paint behind the [child].
///
......@@ -337,10 +343,10 @@ class Container extends StatelessWidget {
///
/// The [child] is not clipped to the decoration. To clip a child to the shape
/// of a particular [ShapeDecoration], consider using a [ClipPath] widget.
final Decoration? decoration;
final Decoration decoration;
/// The decoration to paint in front of the [child].
final Decoration? foregroundDecoration;
final Decoration foregroundDecoration;
/// Additional constraints to apply to the child.
///
......@@ -348,13 +354,13 @@ class Container extends StatelessWidget {
/// `constraints` argument to set this property.
///
/// The [padding] goes inside the constraints.
final BoxConstraints? constraints;
final BoxConstraints constraints;
/// Empty space to surround the [decoration] and [child].
final EdgeInsetsGeometry? margin;
final EdgeInsetsGeometry margin;
/// The transformation matrix to apply before painting the container.
final Matrix4? transform;
final Matrix4 transform;
/// The clip behavior when [Container.decoration] is not null.
///
......@@ -366,20 +372,20 @@ class Container extends StatelessWidget {
/// method throws an [UnsupportedError].)
final Clip clipBehavior;
EdgeInsetsGeometry? get _paddingIncludingDecoration {
if (decoration == null || decoration!.padding == null)
EdgeInsetsGeometry get _paddingIncludingDecoration {
if (decoration == null || decoration.padding == null)
return padding;
final EdgeInsetsGeometry? decorationPadding = decoration!.padding;
final EdgeInsetsGeometry decorationPadding = decoration.padding;
if (padding == null)
return decorationPadding;
return padding!.add(decorationPadding!);
return padding.add(decorationPadding);
}
@override
Widget build(BuildContext context) {
Widget? current = child;
Widget current = child;
if (child == null && (constraints == null || !constraints!.isTight)) {
if (child == null && (constraints == null || !constraints.isTight)) {
current = LimitedBox(
maxWidth: 0.0,
maxHeight: 0.0,
......@@ -388,21 +394,21 @@ class Container extends StatelessWidget {
}
if (alignment != null)
current = Align(alignment: alignment!, child: current);
current = Align(alignment: alignment, child: current);
final EdgeInsetsGeometry? effectivePadding = _paddingIncludingDecoration;
final EdgeInsetsGeometry effectivePadding = _paddingIncludingDecoration;
if (effectivePadding != null)
current = Padding(padding: effectivePadding, child: current);
if (color != null)
current = ColoredBox(color: color!, child: current);
current = ColoredBox(color: color, child: current);
if (clipBehavior != Clip.none) {
assert(decoration != null);
current = ClipPath(
clipper: _DecorationClipper(
textDirection: Directionality.of(context),
decoration: decoration!,
decoration: decoration
),
clipBehavior: clipBehavior,
child: current,
......@@ -410,26 +416,26 @@ class Container extends StatelessWidget {
}
if (decoration != null)
current = DecoratedBox(decoration: decoration!, child: current);
current = DecoratedBox(decoration: decoration, child: current);
if (foregroundDecoration != null) {
current = DecoratedBox(
decoration: foregroundDecoration!,
decoration: foregroundDecoration,
position: DecorationPosition.foreground,
child: current,
);
}
if (constraints != null)
current = ConstrainedBox(constraints: constraints!, child: current);
current = ConstrainedBox(constraints: constraints, child: current);
if (margin != null)
current = Padding(padding: margin!, child: current);
current = Padding(padding: margin, child: current);
if (transform != null)
current = Transform(transform: transform!, child: current);
current = Transform(transform: transform, child: current);
return current!;
return current;
}
@override
......@@ -452,8 +458,8 @@ class Container extends StatelessWidget {
/// A clipper that uses [Decoration.getClipPath] to clip.
class _DecorationClipper extends CustomClipper<Path> {
_DecorationClipper({
TextDirection? textDirection,
required this.decoration
TextDirection textDirection,
@required this.decoration
}) : assert(decoration != null),
textDirection = textDirection ?? TextDirection.ltr;
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:collection';
import 'dart:developer' show Timeline; // to disambiguate reference in dartdocs below
......@@ -53,7 +55,7 @@ typedef RebuildDirtyWidgetCallback = void Function(Element e, bool builtOnce);
/// rebuilds occurred when the
/// `ext.flutter.inspector.trackRebuildDirtyWidgets` service extension is
/// enabled.
RebuildDirtyWidgetCallback? debugOnRebuildDirtyWidget;
RebuildDirtyWidgetCallback debugOnRebuildDirtyWidget;
/// Log all calls to [BuildOwner.buildScope].
///
......@@ -108,13 +110,13 @@ bool debugProfileBuildsEnabled = false;
/// Show banners for deprecated widgets.
bool debugHighlightDeprecatedWidgets = false;
Key? _firstNonUniqueKey(Iterable<Widget> widgets) {
Key _firstNonUniqueKey(Iterable<Widget> widgets) {
final Set<Key> keySet = HashSet<Key>();
for (final Widget widget in widgets) {
assert(widget != null);
if (widget.key == null)
continue;
if (!keySet.add(widget.key!))
if (!keySet.add(widget.key))
return widget.key;
}
return null;
......@@ -136,7 +138,7 @@ Key? _firstNonUniqueKey(Iterable<Widget> widgets) {
/// Does nothing if asserts are disabled. Always returns true.
bool debugChildrenHaveDuplicateKeys(Widget parent, Iterable<Widget> children) {
assert(() {
final Key? nonUniqueKey = _firstNonUniqueKey(children);
final Key nonUniqueKey = _firstNonUniqueKey(children);
if (nonUniqueKey != null) {
throw FlutterError(
'Duplicate keys found.\n'
......@@ -163,7 +165,7 @@ bool debugChildrenHaveDuplicateKeys(Widget parent, Iterable<Widget> children) {
/// Does nothing if asserts are disabled. Always returns true.
bool debugItemsHaveDuplicateKeys(Iterable<Widget> items) {
assert(() {
final Key? nonUniqueKey = _firstNonUniqueKey(items);
final Key nonUniqueKey = _firstNonUniqueKey(items);
if (nonUniqueKey != null)
throw FlutterError('Duplicate key found: $nonUniqueKey.');
return true;
......@@ -260,7 +262,7 @@ bool debugCheckHasMediaQuery(BuildContext context) {
/// with the more generic advice regarding [Directionality].
///
/// Does nothing if asserts are disabled. Always returns true.
bool debugCheckHasDirectionality(BuildContext context, { String? why, String? hint, String? alternative }) {
bool debugCheckHasDirectionality(BuildContext context, { String why, String hint, String alternative }) {
assert(() {
if (context.widget is! Directionality && context.findAncestorWidgetOfExactType<Directionality>() == null) {
why = why == null ? '' : ' $why';
......@@ -294,7 +296,7 @@ bool debugCheckHasDirectionality(BuildContext context, { String? why, String? hi
/// function returned a non-null value, as typically required.
///
/// Does nothing when asserts are disabled.
void debugWidgetBuilderValue(Widget widget, Widget? built) {
void debugWidgetBuilderValue(Widget widget, Widget built) {
assert(() {
if (built == null) {
throw FlutterError.fromParts(<DiagnosticsNode>[
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'framework.dart';
/// Provides non-leaking access to a [BuildContext].
......@@ -29,21 +31,21 @@ class DisposableBuildContext<T extends State> {
/// The [State] must not be null, and [State.mounted] must be true.
DisposableBuildContext(this._state)
: assert(_state != null),
assert(_state!.mounted, 'A DisposableBuildContext was given a BuildContext for an Element that is not mounted.');
assert(_state.mounted, 'A DisposableBuildContext was given a BuildContext for an Element that is not mounted.');
T? _state;
T _state;
/// Provides safe access to the build context.
///
/// If [dispose] has been called, will return null.
///
/// Otherwise, asserts the [_state] is still mounted and returns its context.
BuildContext? get context {
BuildContext get context {
assert(_debugValidate());
if (_state == null) {
return null;
}
return _state!.context;
return _state.context;
}
/// Called from asserts or tests to determine whether this object is in a
......@@ -53,7 +55,7 @@ class DisposableBuildContext<T extends State> {
/// but the state this is tracking is unmounted.
bool _debugValidate() {
assert(
_state == null || _state!.mounted,
_state == null || _state.mounted,
'A DisposableBuildContext tried to access the BuildContext of a disposed '
'State object. This can happen when the creator of this '
'DisposableBuildContext fails to call dispose when it is disposed.',
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'basic.dart';
import 'framework.dart';
......@@ -13,8 +15,8 @@ import 'framework.dart';
/// The `animation` provided to the builder always runs forward from 0.0 to 1.0.
typedef AnimatedTransitionBuilder = Widget Function(
BuildContext context,
Animation<double?> animation,
Widget? child,
Animation<double> animation,
Widget child,
);
/// A transition builder that animates its [child] based on the
......@@ -36,10 +38,10 @@ class DualTransitionBuilder extends StatefulWidget {
/// The [animation], [forwardBuilder], and [reverseBuilder] arguments are
/// required and must not be null.
const DualTransitionBuilder({
Key? key,
required this.animation,
required this.forwardBuilder,
required this.reverseBuilder,
Key key,
@required this.animation,
@required this.forwardBuilder,
@required this.reverseBuilder,
this.child,
}) : assert(animation != null),
assert(forwardBuilder != null),
......@@ -87,14 +89,14 @@ class DualTransitionBuilder extends StatefulWidget {
///
/// This child widget will be wrapped by the transitions built by
/// [forwardBuilder] and [reverseBuilder].
final Widget? child;
final Widget child;
@override
State<DualTransitionBuilder> createState() => _DualTransitionBuilderState();
}
class _DualTransitionBuilderState extends State<DualTransitionBuilder> {
late AnimationStatus _effectiveAnimationStatus;
AnimationStatus _effectiveAnimationStatus;
final ProxyAnimation _forwardAnimation = ProxyAnimation();
final ProxyAnimation _reverseAnimation = ProxyAnimation();
......@@ -132,8 +134,8 @@ class _DualTransitionBuilderState extends State<DualTransitionBuilder> {
// yield a disjoint experience since the forward and reverse transitions are
// very different.
AnimationStatus _calculateEffectiveAnimationStatus({
required AnimationStatus lastEffective,
required AnimationStatus current,
@required AnimationStatus lastEffective,
@required AnimationStatus current,
}) {
assert(current != null);
assert(lastEffective != null);
......@@ -150,6 +152,7 @@ class _DualTransitionBuilderState extends State<DualTransitionBuilder> {
case AnimationStatus.reverse:
return lastEffective;
}
break;
case AnimationStatus.reverse:
switch (lastEffective) {
case AnimationStatus.dismissed:
......@@ -159,7 +162,9 @@ class _DualTransitionBuilderState extends State<DualTransitionBuilder> {
case AnimationStatus.forward:
return lastEffective;
}
break;
}
return null; // unreachable
}
void _updateAnimations() {
......
This diff is collapsed.
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/rendering.dart';
import 'basic.dart';
......@@ -9,10 +11,10 @@ import 'framework.dart';
class _GridPaperPainter extends CustomPainter {
const _GridPaperPainter({
required this.color,
required this.interval,
required this.divisions,
required this.subdivisions,
this.color,
this.interval,
this.divisions,
this.subdivisions,
});
final Color color;
......@@ -58,7 +60,7 @@ class _GridPaperPainter extends CustomPainter {
class GridPaper extends StatelessWidget {
/// Creates a widget that draws a rectilinear grid of 1-pixel-wide lines.
const GridPaper({
Key? key,
Key key,
this.color = const Color(0x7FC3E8F3),
this.interval = 100.0,
this.divisions = 2,
......@@ -103,7 +105,7 @@ class GridPaper extends StatelessWidget {
/// The widget below this widget in the tree.
///
/// {@macro flutter.widgets.child}
final Widget? child;
final Widget child;
@override
Widget build(BuildContext context) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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