mirror of
https://github.com/flutter/flutter
synced 2024-10-13 03:32:55 +00:00
migrate some cupertino files to nullsafety (#66024)
* migrate some cupertino files to nullsafety * address review comments * address review comments
This commit is contained in:
parent
71c1f6c3e4
commit
45fa60eb3e
|
@ -2,8 +2,6 @@
|
|||
// 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/widgets.dart';
|
||||
|
@ -28,7 +26,7 @@ const Color _kActiveTickColor = CupertinoDynamicColor.withBrightness(
|
|||
class CupertinoActivityIndicator extends StatefulWidget {
|
||||
/// Creates an iOS-style activity indicator that spins clockwise.
|
||||
const CupertinoActivityIndicator({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.animating = true,
|
||||
this.radius = _kDefaultIndicatorRadius,
|
||||
}) : assert(animating != null),
|
||||
|
@ -44,7 +42,7 @@ class CupertinoActivityIndicator extends StatefulWidget {
|
|||
/// will be shown) and 1.0 (all ticks will be shown) inclusive. Defaults
|
||||
/// to 1.0.
|
||||
const CupertinoActivityIndicator.partiallyRevealed({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.radius = _kDefaultIndicatorRadius,
|
||||
this.progress = 1.0,
|
||||
}) : assert(radius != null),
|
||||
|
@ -80,7 +78,7 @@ class CupertinoActivityIndicator extends StatefulWidget {
|
|||
|
||||
class _CupertinoActivityIndicatorState extends State<CupertinoActivityIndicator>
|
||||
with SingleTickerProviderStateMixin {
|
||||
AnimationController _controller;
|
||||
late AnimationController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -121,7 +119,7 @@ class _CupertinoActivityIndicatorState extends State<CupertinoActivityIndicator>
|
|||
painter: _CupertinoActivityIndicatorPainter(
|
||||
position: _controller,
|
||||
activeColor:
|
||||
CupertinoDynamicColor.resolve(_kActiveTickColor, context),
|
||||
CupertinoDynamicColor.resolve(_kActiveTickColor, context)!,
|
||||
radius: widget.radius,
|
||||
progress: widget.progress,
|
||||
),
|
||||
|
@ -150,10 +148,10 @@ const int _partiallyRevealedAlpha = 147;
|
|||
|
||||
class _CupertinoActivityIndicatorPainter extends CustomPainter {
|
||||
_CupertinoActivityIndicatorPainter({
|
||||
@required this.position,
|
||||
@required this.activeColor,
|
||||
@required this.radius,
|
||||
@required this.progress,
|
||||
required this.position,
|
||||
required this.activeColor,
|
||||
required this.radius,
|
||||
required this.progress,
|
||||
}) : tickFundamentalRRect = RRect.fromLTRBXY(
|
||||
-radius / _kDefaultIndicatorRadius,
|
||||
-radius / 3.0,
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// 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/widgets.dart';
|
||||
|
||||
|
@ -34,15 +32,15 @@ const EdgeInsets _kBackgroundButtonPadding = EdgeInsets.symmetric(
|
|||
class CupertinoButton extends StatefulWidget {
|
||||
/// Creates an iOS-style button.
|
||||
const CupertinoButton({
|
||||
Key key,
|
||||
@required this.child,
|
||||
Key? key,
|
||||
required this.child,
|
||||
this.padding,
|
||||
this.color,
|
||||
this.disabledColor = CupertinoColors.quaternarySystemFill,
|
||||
this.minSize = kMinInteractiveDimensionCupertino,
|
||||
this.pressedOpacity = 0.4,
|
||||
this.borderRadius = const BorderRadius.all(Radius.circular(8.0)),
|
||||
@required this.onPressed,
|
||||
required this.onPressed,
|
||||
}) : assert(pressedOpacity == null || (pressedOpacity >= 0.0 && pressedOpacity <= 1.0)),
|
||||
assert(disabledColor != null),
|
||||
_filled = false,
|
||||
|
@ -55,14 +53,14 @@ class CupertinoButton extends StatefulWidget {
|
|||
/// To specify a custom background color, use the [color] argument of the
|
||||
/// default constructor.
|
||||
const CupertinoButton.filled({
|
||||
Key key,
|
||||
@required this.child,
|
||||
Key? key,
|
||||
required this.child,
|
||||
this.padding,
|
||||
this.disabledColor = CupertinoColors.quaternarySystemFill,
|
||||
this.minSize = kMinInteractiveDimensionCupertino,
|
||||
this.pressedOpacity = 0.4,
|
||||
this.borderRadius = const BorderRadius.all(Radius.circular(8.0)),
|
||||
@required this.onPressed,
|
||||
required this.onPressed,
|
||||
}) : assert(pressedOpacity == null || (pressedOpacity >= 0.0 && pressedOpacity <= 1.0)),
|
||||
assert(disabledColor != null),
|
||||
color = null,
|
||||
|
@ -77,7 +75,7 @@ class CupertinoButton extends StatefulWidget {
|
|||
/// The amount of space to surround the child inside the bounds of the button.
|
||||
///
|
||||
/// Defaults to 16.0 pixels.
|
||||
final EdgeInsetsGeometry padding;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
|
||||
/// The color of the button's background.
|
||||
///
|
||||
|
@ -85,7 +83,7 @@ class CupertinoButton extends StatefulWidget {
|
|||
///
|
||||
/// Defaults to the [CupertinoTheme]'s `primaryColor` when the
|
||||
/// [CupertinoButton.filled] constructor is used.
|
||||
final Color color;
|
||||
final Color? color;
|
||||
|
||||
/// The color of the button's background when the button is disabled.
|
||||
///
|
||||
|
@ -98,25 +96,25 @@ class CupertinoButton extends StatefulWidget {
|
|||
/// The callback that is called when the button is tapped or otherwise activated.
|
||||
///
|
||||
/// If this is set to null, the button will be disabled.
|
||||
final VoidCallback onPressed;
|
||||
final VoidCallback? onPressed;
|
||||
|
||||
/// Minimum size of the button.
|
||||
///
|
||||
/// Defaults to kMinInteractiveDimensionCupertino which the iOS Human
|
||||
/// Interface Guidelines recommends as the minimum tappable area.
|
||||
final double minSize;
|
||||
final double? minSize;
|
||||
|
||||
/// The opacity that the button will fade to when it is pressed.
|
||||
/// The button will have an opacity of 1.0 when it is not pressed.
|
||||
///
|
||||
/// This defaults to 0.4. If null, opacity will not change on pressed if using
|
||||
/// your own custom effects is desired.
|
||||
final double pressedOpacity;
|
||||
final double? pressedOpacity;
|
||||
|
||||
/// The radius of the button's corners when it has a background color.
|
||||
///
|
||||
/// Defaults to round corners of 8 logical pixels.
|
||||
final BorderRadius borderRadius;
|
||||
final BorderRadius? borderRadius;
|
||||
|
||||
final bool _filled;
|
||||
|
||||
|
@ -140,8 +138,8 @@ class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProv
|
|||
static const Duration kFadeInDuration = Duration(milliseconds: 100);
|
||||
final Tween<double> _opacityTween = Tween<double>(begin: 1.0);
|
||||
|
||||
AnimationController _animationController;
|
||||
Animation<double> _opacityAnimation;
|
||||
late AnimationController _animationController;
|
||||
late Animation<double> _opacityAnimation;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -170,7 +168,6 @@ class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProv
|
|||
@override
|
||||
void dispose() {
|
||||
_animationController.dispose();
|
||||
_animationController = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -214,12 +211,12 @@ class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProv
|
|||
Widget build(BuildContext context) {
|
||||
final bool enabled = widget.enabled;
|
||||
final CupertinoThemeData themeData = CupertinoTheme.of(context);
|
||||
final Color primaryColor = themeData.primaryColor;
|
||||
final Color backgroundColor = widget.color == null
|
||||
final Color? primaryColor = themeData.primaryColor;
|
||||
final Color? backgroundColor = widget.color == null
|
||||
? (widget._filled ? primaryColor : null)
|
||||
: CupertinoDynamicColor.resolve(widget.color, context);
|
||||
|
||||
final Color foregroundColor = backgroundColor != null
|
||||
final Color? foregroundColor = backgroundColor != null
|
||||
? themeData.primaryContrastingColor
|
||||
: enabled
|
||||
? primaryColor
|
||||
|
@ -239,9 +236,9 @@ class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProv
|
|||
constraints: widget.minSize == null
|
||||
? const BoxConstraints()
|
||||
: BoxConstraints(
|
||||
minWidth: widget.minSize,
|
||||
minHeight: widget.minSize,
|
||||
),
|
||||
minWidth: widget.minSize!,
|
||||
minHeight: widget.minSize!,
|
||||
),
|
||||
child: FadeTransition(
|
||||
opacity: _opacityAnimation,
|
||||
child: DecoratedBox(
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// 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 iOS Human
|
||||
/// Interface Guidelines.
|
||||
///
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// 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/widgets.dart';
|
||||
|
||||
/// Identifiers for the supported Cupertino icons.
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// 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';
|
||||
import 'package:flutter/services.dart';
|
||||
|
@ -70,7 +68,7 @@ class CupertinoPicker extends StatefulWidget {
|
|||
/// will loop the list back to the beginning. If set to false, the list will
|
||||
/// stop scrolling when you reach the end or the beginning.
|
||||
CupertinoPicker({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.diameterRatio = _kDefaultDiameterRatio,
|
||||
this.backgroundColor,
|
||||
this.offAxisFraction = 0.0,
|
||||
|
@ -78,9 +76,9 @@ class CupertinoPicker extends StatefulWidget {
|
|||
this.magnification = 1.0,
|
||||
this.scrollController,
|
||||
this.squeeze = _kSqueeze,
|
||||
@required this.itemExtent,
|
||||
@required this.onSelectedItemChanged,
|
||||
@required List<Widget> children,
|
||||
required this.itemExtent,
|
||||
required this.onSelectedItemChanged,
|
||||
required List<Widget> children,
|
||||
bool looping = false,
|
||||
}) : assert(children != null),
|
||||
assert(diameterRatio != null),
|
||||
|
@ -113,7 +111,7 @@ class CupertinoPicker extends StatefulWidget {
|
|||
/// (i.e. the picker is going to have a completely transparent background), to match
|
||||
/// the native UIPicker and UIDatePicker.
|
||||
CupertinoPicker.builder({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.diameterRatio = _kDefaultDiameterRatio,
|
||||
this.backgroundColor,
|
||||
this.offAxisFraction = 0.0,
|
||||
|
@ -121,10 +119,10 @@ class CupertinoPicker extends StatefulWidget {
|
|||
this.magnification = 1.0,
|
||||
this.scrollController,
|
||||
this.squeeze = _kSqueeze,
|
||||
@required this.itemExtent,
|
||||
@required this.onSelectedItemChanged,
|
||||
@required IndexedWidgetBuilder itemBuilder,
|
||||
int childCount,
|
||||
required this.itemExtent,
|
||||
required this.onSelectedItemChanged,
|
||||
required NullableIndexedWidgetBuilder itemBuilder,
|
||||
int? childCount,
|
||||
}) : assert(itemBuilder != null),
|
||||
assert(diameterRatio != null),
|
||||
assert(diameterRatio > 0.0, RenderListWheelViewport.diameterRatioZeroMessage),
|
||||
|
@ -153,7 +151,7 @@ class CupertinoPicker extends StatefulWidget {
|
|||
///
|
||||
/// Any alpha value less 255 (fully opaque) will cause the removal of the
|
||||
/// wheel list edge fade gradient from rendering of the widget.
|
||||
final Color backgroundColor;
|
||||
final Color? backgroundColor;
|
||||
|
||||
/// {@macro flutter.rendering.wheelList.offAxisFraction}
|
||||
final double offAxisFraction;
|
||||
|
@ -168,7 +166,7 @@ class CupertinoPicker extends StatefulWidget {
|
|||
/// to set the initial item.
|
||||
///
|
||||
/// If null, an implicit one will be created internally.
|
||||
final FixedExtentScrollController scrollController;
|
||||
final FixedExtentScrollController? scrollController;
|
||||
|
||||
/// The uniform height of all children.
|
||||
///
|
||||
|
@ -198,8 +196,8 @@ class CupertinoPicker extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _CupertinoPickerState extends State<CupertinoPicker> {
|
||||
int _lastHapticIndex;
|
||||
FixedExtentScrollController _controller;
|
||||
int? _lastHapticIndex;
|
||||
FixedExtentScrollController? _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -255,7 +253,7 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
|
|||
|
||||
/// Draws the magnifier borders.
|
||||
Widget _buildMagnifierScreen() {
|
||||
final Color resolvedBorderColor = CupertinoDynamicColor.resolve(_kHighlighterBorder, context);
|
||||
final Color resolvedBorderColor = CupertinoDynamicColor.resolve(_kHighlighterBorder, context)!;
|
||||
|
||||
return IgnorePointer(
|
||||
child: Center(
|
||||
|
@ -276,7 +274,7 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Color resolvedBackgroundColor = CupertinoDynamicColor.resolve(widget.backgroundColor, context);
|
||||
final Color? resolvedBackgroundColor = CupertinoDynamicColor.resolve(widget.backgroundColor, context);
|
||||
|
||||
final Widget result = DefaultTextStyle(
|
||||
style: CupertinoTheme.of(context).textTheme.pickerTextStyle,
|
||||
|
@ -284,7 +282,7 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
|
|||
children: <Widget>[
|
||||
Positioned.fill(
|
||||
child: _CupertinoPickerSemantics(
|
||||
scrollController: widget.scrollController ?? _controller,
|
||||
scrollController: widget.scrollController ?? _controller!,
|
||||
child: ListWheelScrollView.useDelegate(
|
||||
controller: widget.scrollController ?? _controller,
|
||||
physics: const FixedExtentScrollPhysics(),
|
||||
|
@ -321,38 +319,45 @@ class _CupertinoPickerState extends State<CupertinoPicker> {
|
|||
// scroll controller.
|
||||
class _CupertinoPickerSemantics extends SingleChildRenderObjectWidget {
|
||||
const _CupertinoPickerSemantics({
|
||||
Key key,
|
||||
Widget child,
|
||||
@required this.scrollController,
|
||||
Key? key,
|
||||
Widget? child,
|
||||
required this.scrollController,
|
||||
}) : super(key: key, child: child);
|
||||
|
||||
final FixedExtentScrollController scrollController;
|
||||
|
||||
@override
|
||||
RenderObject createRenderObject(BuildContext context) => _RenderCupertinoPickerSemantics(scrollController, Directionality.of(context));
|
||||
RenderObject createRenderObject(BuildContext context) {
|
||||
assert(debugCheckHasDirectionality(context));
|
||||
return _RenderCupertinoPickerSemantics(scrollController, Directionality.of(context)!);
|
||||
}
|
||||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, covariant _RenderCupertinoPickerSemantics renderObject) {
|
||||
assert(debugCheckHasDirectionality(context));
|
||||
renderObject
|
||||
..textDirection = Directionality.of(context)
|
||||
..textDirection = Directionality.of(context)!
|
||||
..controller = scrollController;
|
||||
}
|
||||
}
|
||||
|
||||
class _RenderCupertinoPickerSemantics extends RenderProxyBox {
|
||||
_RenderCupertinoPickerSemantics(FixedExtentScrollController controller, this._textDirection) {
|
||||
this.controller = controller;
|
||||
_updateController(null, controller);
|
||||
}
|
||||
|
||||
FixedExtentScrollController get controller => _controller;
|
||||
FixedExtentScrollController _controller;
|
||||
set controller(FixedExtentScrollController value) {
|
||||
if (value == _controller)
|
||||
late FixedExtentScrollController _controller;
|
||||
set controller(FixedExtentScrollController value) => _updateController(_controller, value);
|
||||
|
||||
// This method exists to allow controller to be non-null. It is only called with a null oldValue from construtor.
|
||||
void _updateController(FixedExtentScrollController? oldValue, FixedExtentScrollController value) {
|
||||
if (value == oldValue)
|
||||
return;
|
||||
if (_controller != null)
|
||||
_controller.removeListener(_handleScrollUpdate);
|
||||
if (oldValue != null)
|
||||
oldValue.removeListener(_handleScrollUpdate);
|
||||
else
|
||||
_currentIndex = value.initialItem ?? 0;
|
||||
_currentIndex = value.initialItem;
|
||||
value.addListener(_handleScrollUpdate);
|
||||
_controller = value;
|
||||
}
|
||||
|
@ -399,15 +404,15 @@ class _RenderCupertinoPickerSemantics extends RenderProxyBox {
|
|||
final Map<int, SemanticsNode> indexedChildren = <int, SemanticsNode>{};
|
||||
scrollable.visitChildren((SemanticsNode child) {
|
||||
assert(child.indexInParent != null);
|
||||
indexedChildren[child.indexInParent] = child;
|
||||
indexedChildren[child.indexInParent!] = child;
|
||||
return true;
|
||||
});
|
||||
if (indexedChildren[_currentIndex] == null) {
|
||||
return node.updateWith(config: config);
|
||||
}
|
||||
config.value = indexedChildren[_currentIndex].label;
|
||||
final SemanticsNode previousChild = indexedChildren[_currentIndex - 1];
|
||||
final SemanticsNode nextChild = indexedChildren[_currentIndex + 1];
|
||||
config.value = indexedChildren[_currentIndex]!.label;
|
||||
final SemanticsNode? previousChild = indexedChildren[_currentIndex - 1];
|
||||
final SemanticsNode? nextChild = indexedChildren[_currentIndex + 1];
|
||||
if (nextChild != null) {
|
||||
config.increasedValue = nextChild.label;
|
||||
config.onIncrease = _handleIncrease;
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
// 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 'dart:math';
|
||||
|
||||
import 'package:flutter/rendering.dart';
|
||||
|
@ -18,10 +17,10 @@ const double _kActivityIndicatorMargin = 16.0;
|
|||
|
||||
class _CupertinoSliverRefresh extends SingleChildRenderObjectWidget {
|
||||
const _CupertinoSliverRefresh({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.refreshIndicatorLayoutExtent = 0.0,
|
||||
this.hasLayoutExtent = false,
|
||||
Widget child,
|
||||
Widget? child,
|
||||
}) : assert(refreshIndicatorLayoutExtent != null),
|
||||
assert(refreshIndicatorLayoutExtent >= 0.0),
|
||||
assert(hasLayoutExtent != null),
|
||||
|
@ -61,9 +60,9 @@ class _CupertinoSliverRefresh extends SingleChildRenderObjectWidget {
|
|||
class _RenderCupertinoSliverRefresh extends RenderSliver
|
||||
with RenderObjectWithChildMixin<RenderBox> {
|
||||
_RenderCupertinoSliverRefresh({
|
||||
@required double refreshIndicatorExtent,
|
||||
@required bool hasLayoutExtent,
|
||||
RenderBox child,
|
||||
required double refreshIndicatorExtent,
|
||||
required bool hasLayoutExtent,
|
||||
RenderBox? child,
|
||||
}) : assert(refreshIndicatorExtent != null),
|
||||
assert(refreshIndicatorExtent >= 0.0),
|
||||
assert(hasLayoutExtent != null),
|
||||
|
@ -135,7 +134,7 @@ class _RenderCupertinoSliverRefresh extends RenderSliver
|
|||
// Layout the child giving it the space of the currently dragged overscroll
|
||||
// which may or may not include a sliver layout extent space that it will
|
||||
// keep after the user lets go during the refresh process.
|
||||
child.layout(
|
||||
child!.layout(
|
||||
constraints.asBoxConstraints(
|
||||
maxExtent: layoutExtent
|
||||
// Plus only the overscrolled portion immediately preceding this
|
||||
|
@ -153,11 +152,11 @@ class _RenderCupertinoSliverRefresh extends RenderSliver
|
|||
// layoutExtent may be zero. Check layoutExtent also since even
|
||||
// with a layoutExtent, the indicator builder may decide to not
|
||||
// build anything.
|
||||
max(child.size.height, layoutExtent) - constraints.scrollOffset,
|
||||
max(child!.size.height, layoutExtent) - constraints.scrollOffset,
|
||||
0.0,
|
||||
),
|
||||
maxPaintExtent: max(
|
||||
max(child.size.height, layoutExtent) - constraints.scrollOffset,
|
||||
max(child!.size.height, layoutExtent) - constraints.scrollOffset,
|
||||
0.0,
|
||||
),
|
||||
layoutExtent: max(layoutExtent - constraints.scrollOffset, 0.0),
|
||||
|
@ -171,8 +170,8 @@ class _RenderCupertinoSliverRefresh extends RenderSliver
|
|||
@override
|
||||
void paint(PaintingContext paintContext, Offset offset) {
|
||||
if (constraints.overlap < 0.0 ||
|
||||
constraints.scrollOffset + child.size.height > 0) {
|
||||
paintContext.paintChild(child, offset);
|
||||
constraints.scrollOffset + child!.size.height > 0) {
|
||||
paintContext.paintChild(child!, offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,7 +344,7 @@ class CupertinoSliverRefreshControl extends StatefulWidget {
|
|||
/// The [onRefresh] argument will be called when pulled far enough to trigger
|
||||
/// a refresh.
|
||||
const CupertinoSliverRefreshControl({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.refreshTriggerPullDistance = _defaultRefreshTriggerPullDistance,
|
||||
this.refreshIndicatorExtent = _defaultRefreshIndicatorExtent,
|
||||
this.builder = buildRefreshIndicator,
|
||||
|
@ -389,7 +388,7 @@ class CupertinoSliverRefreshControl extends StatefulWidget {
|
|||
///
|
||||
/// Will not be called when the available space is zero such as before any
|
||||
/// overscroll.
|
||||
final RefreshControlIndicatorBuilder builder;
|
||||
final RefreshControlIndicatorBuilder? builder;
|
||||
|
||||
/// Callback invoked when pulled by [refreshTriggerPullDistance].
|
||||
///
|
||||
|
@ -399,7 +398,7 @@ class CupertinoSliverRefreshControl extends StatefulWidget {
|
|||
/// Can be null, in which case a single frame of [RefreshIndicatorMode.armed]
|
||||
/// state will be drawn before going immediately to the [RefreshIndicatorMode.done]
|
||||
/// where the sliver will start retracting.
|
||||
final RefreshCallback onRefresh;
|
||||
final RefreshCallback? onRefresh;
|
||||
|
||||
static const double _defaultRefreshTriggerPullDistance = 100.0;
|
||||
static const double _defaultRefreshIndicatorExtent = 60.0;
|
||||
|
@ -408,7 +407,7 @@ class CupertinoSliverRefreshControl extends StatefulWidget {
|
|||
/// state that gets passed into the [builder] function. Used for testing.
|
||||
@visibleForTesting
|
||||
static RefreshIndicatorMode state(BuildContext context) {
|
||||
final _CupertinoSliverRefreshControlState state = context.findAncestorStateOfType<_CupertinoSliverRefreshControlState>();
|
||||
final _CupertinoSliverRefreshControlState state = context.findAncestorStateOfType<_CupertinoSliverRefreshControlState>()!;
|
||||
return state.refreshState;
|
||||
}
|
||||
|
||||
|
@ -483,9 +482,9 @@ class _CupertinoSliverRefreshControlState extends State<CupertinoSliverRefreshCo
|
|||
// original `refreshTriggerPullDistance` is left.
|
||||
static const double _inactiveResetOverscrollFraction = 0.1;
|
||||
|
||||
RefreshIndicatorMode refreshState;
|
||||
late RefreshIndicatorMode refreshState;
|
||||
// [Future] returned by the widget's `onRefresh`.
|
||||
Future<void> refreshTask;
|
||||
Future<void>? refreshTask;
|
||||
// The amount of space available from the inner indicator box's perspective.
|
||||
//
|
||||
// The value is the sum of the sliver's layout extent and the overscroll
|
||||
|
@ -512,10 +511,10 @@ class _CupertinoSliverRefreshControlState extends State<CupertinoSliverRefreshCo
|
|||
nextState = RefreshIndicatorMode.done;
|
||||
// Either schedule the RenderSliver to re-layout on the next frame
|
||||
// when not currently in a frame or schedule it on the next frame.
|
||||
if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.idle) {
|
||||
if (SchedulerBinding.instance!.schedulerPhase == SchedulerPhase.idle) {
|
||||
setState(() => hasSliverLayoutExtent = false);
|
||||
} else {
|
||||
SchedulerBinding.instance.addPostFrameCallback((Duration timestamp) {
|
||||
SchedulerBinding.instance!.addPostFrameCallback((Duration timestamp) {
|
||||
setState(() => hasSliverLayoutExtent = false);
|
||||
});
|
||||
}
|
||||
|
@ -541,8 +540,8 @@ class _CupertinoSliverRefreshControlState extends State<CupertinoSliverRefreshCo
|
|||
// Call onRefresh after this frame finished since the function is
|
||||
// user supplied and we're always here in the middle of the sliver's
|
||||
// performLayout.
|
||||
SchedulerBinding.instance.addPostFrameCallback((Duration timestamp) {
|
||||
refreshTask = widget.onRefresh()..whenComplete(() {
|
||||
SchedulerBinding.instance!.addPostFrameCallback((Duration timestamp) {
|
||||
refreshTask = widget.onRefresh!()..whenComplete(() {
|
||||
if (mounted) {
|
||||
setState(() => refreshTask = null);
|
||||
// Trigger one more transition because by this time, BoxConstraint's
|
||||
|
@ -557,9 +556,6 @@ class _CupertinoSliverRefreshControlState extends State<CupertinoSliverRefreshCo
|
|||
}
|
||||
return RefreshIndicatorMode.armed;
|
||||
}
|
||||
// Don't continue here. We can never possibly call onRefresh and
|
||||
// progress to the next state in one [computeNextState] call.
|
||||
break;
|
||||
case RefreshIndicatorMode.armed:
|
||||
if (refreshState == RefreshIndicatorMode.armed && refreshTask == null) {
|
||||
goToDone();
|
||||
|
@ -610,7 +606,7 @@ class _CupertinoSliverRefreshControlState extends State<CupertinoSliverRefreshCo
|
|||
latestIndicatorBoxExtent = constraints.maxHeight;
|
||||
refreshState = transitionNextState();
|
||||
if (widget.builder != null && latestIndicatorBoxExtent > 0) {
|
||||
return widget.builder(
|
||||
return widget.builder!(
|
||||
context,
|
||||
refreshState,
|
||||
latestIndicatorBoxExtent,
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// 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 'dart:ui' show lerpDouble;
|
||||
|
||||
|
@ -55,9 +53,9 @@ class CupertinoSlider extends StatefulWidget {
|
|||
/// * [onChangeEnd] is called when the user is done selecting a new value for
|
||||
/// the slider.
|
||||
const CupertinoSlider({
|
||||
Key key,
|
||||
@required this.value,
|
||||
@required this.onChanged,
|
||||
Key? key,
|
||||
required this.value,
|
||||
required this.onChanged,
|
||||
this.onChangeStart,
|
||||
this.onChangeEnd,
|
||||
this.min = 0.0,
|
||||
|
@ -110,7 +108,7 @@ class CupertinoSlider extends StatefulWidget {
|
|||
/// changing the value.
|
||||
/// * [onChangeEnd] for a callback that is called when the user stops
|
||||
/// changing the value.
|
||||
final ValueChanged<double> onChanged;
|
||||
final ValueChanged<double>? onChanged;
|
||||
|
||||
/// Called when the user starts selecting a new value for the slider.
|
||||
///
|
||||
|
@ -145,7 +143,7 @@ class CupertinoSlider extends StatefulWidget {
|
|||
///
|
||||
/// * [onChangeEnd] for a callback that is called when the value change is
|
||||
/// complete.
|
||||
final ValueChanged<double> onChangeStart;
|
||||
final ValueChanged<double>? onChangeStart;
|
||||
|
||||
/// Called when the user is done selecting a new value for the slider.
|
||||
///
|
||||
|
@ -177,7 +175,7 @@ class CupertinoSlider extends StatefulWidget {
|
|||
///
|
||||
/// * [onChangeStart] for a callback that is called when a value change
|
||||
/// begins.
|
||||
final ValueChanged<double> onChangeEnd;
|
||||
final ValueChanged<double>? onChangeEnd;
|
||||
|
||||
/// The minimum value the user can select.
|
||||
///
|
||||
|
@ -192,12 +190,12 @@ class CupertinoSlider extends StatefulWidget {
|
|||
/// The number of discrete divisions.
|
||||
///
|
||||
/// If null, the slider is continuous.
|
||||
final int divisions;
|
||||
final int? divisions;
|
||||
|
||||
/// The color to use for the portion of the slider that has been selected.
|
||||
///
|
||||
/// Defaults to the [CupertinoTheme]'s primary color if null.
|
||||
final Color activeColor;
|
||||
final Color? activeColor;
|
||||
|
||||
/// The color to use for the thumb of the slider.
|
||||
///
|
||||
|
@ -221,20 +219,20 @@ class CupertinoSlider extends StatefulWidget {
|
|||
class _CupertinoSliderState extends State<CupertinoSlider> with TickerProviderStateMixin {
|
||||
void _handleChanged(double value) {
|
||||
assert(widget.onChanged != null);
|
||||
final double lerpValue = lerpDouble(widget.min, widget.max, value);
|
||||
final double lerpValue = lerpDouble(widget.min, widget.max, value)!;
|
||||
if (lerpValue != widget.value) {
|
||||
widget.onChanged(lerpValue);
|
||||
widget.onChanged!(lerpValue);
|
||||
}
|
||||
}
|
||||
|
||||
void _handleDragStart(double value) {
|
||||
assert(widget.onChangeStart != null);
|
||||
widget.onChangeStart(lerpDouble(widget.min, widget.max, value));
|
||||
widget.onChangeStart!(lerpDouble(widget.min, widget.max, value)!);
|
||||
}
|
||||
|
||||
void _handleDragEnd(double value) {
|
||||
assert(widget.onChangeEnd != null);
|
||||
widget.onChangeEnd(lerpDouble(widget.min, widget.max, value));
|
||||
widget.onChangeEnd!(lerpDouble(widget.min, widget.max, value)!);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -245,7 +243,7 @@ class _CupertinoSliderState extends State<CupertinoSlider> with TickerProviderSt
|
|||
activeColor: CupertinoDynamicColor.resolve(
|
||||
widget.activeColor ?? CupertinoTheme.of(context).primaryColor,
|
||||
context,
|
||||
),
|
||||
)!,
|
||||
thumbColor: widget.thumbColor,
|
||||
onChanged: widget.onChanged != null ? _handleChanged : null,
|
||||
onChangeStart: widget.onChangeStart != null ? _handleDragStart : null,
|
||||
|
@ -257,54 +255,56 @@ class _CupertinoSliderState extends State<CupertinoSlider> with TickerProviderSt
|
|||
|
||||
class _CupertinoSliderRenderObjectWidget extends LeafRenderObjectWidget {
|
||||
const _CupertinoSliderRenderObjectWidget({
|
||||
Key key,
|
||||
this.value,
|
||||
Key? key,
|
||||
required this.value,
|
||||
this.divisions,
|
||||
this.activeColor,
|
||||
this.thumbColor,
|
||||
required this.activeColor,
|
||||
required this.thumbColor,
|
||||
this.onChanged,
|
||||
this.onChangeStart,
|
||||
this.onChangeEnd,
|
||||
this.vsync,
|
||||
required this.vsync,
|
||||
}) : super(key: key);
|
||||
|
||||
final double value;
|
||||
final int divisions;
|
||||
final int? divisions;
|
||||
final Color activeColor;
|
||||
final Color thumbColor;
|
||||
final ValueChanged<double> onChanged;
|
||||
final ValueChanged<double> onChangeStart;
|
||||
final ValueChanged<double> onChangeEnd;
|
||||
final ValueChanged<double>? onChanged;
|
||||
final ValueChanged<double>? onChangeStart;
|
||||
final ValueChanged<double>? onChangeEnd;
|
||||
final TickerProvider vsync;
|
||||
|
||||
@override
|
||||
_RenderCupertinoSlider createRenderObject(BuildContext context) {
|
||||
assert(debugCheckHasDirectionality(context));
|
||||
return _RenderCupertinoSlider(
|
||||
value: value,
|
||||
divisions: divisions,
|
||||
activeColor: activeColor,
|
||||
thumbColor: CupertinoDynamicColor.resolve(thumbColor, context),
|
||||
trackColor: CupertinoDynamicColor.resolve(CupertinoColors.systemFill, context),
|
||||
thumbColor: CupertinoDynamicColor.resolve(thumbColor, context)!,
|
||||
trackColor: CupertinoDynamicColor.resolve(CupertinoColors.systemFill, context)!,
|
||||
onChanged: onChanged,
|
||||
onChangeStart: onChangeStart,
|
||||
onChangeEnd: onChangeEnd,
|
||||
vsync: vsync,
|
||||
textDirection: Directionality.of(context),
|
||||
textDirection: Directionality.of(context)!,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, _RenderCupertinoSlider renderObject) {
|
||||
assert(debugCheckHasDirectionality(context));
|
||||
renderObject
|
||||
..value = value
|
||||
..divisions = divisions
|
||||
..activeColor = activeColor
|
||||
..thumbColor = CupertinoDynamicColor.resolve(thumbColor, context)
|
||||
..trackColor = CupertinoDynamicColor.resolve(CupertinoColors.systemFill, context)
|
||||
..thumbColor = CupertinoDynamicColor.resolve(thumbColor, context)!
|
||||
..trackColor = CupertinoDynamicColor.resolve(CupertinoColors.systemFill, context)!
|
||||
..onChanged = onChanged
|
||||
..onChangeStart = onChangeStart
|
||||
..onChangeEnd = onChangeEnd
|
||||
..textDirection = Directionality.of(context);
|
||||
..textDirection = Directionality.of(context)!;
|
||||
// Ticker provider cannot change since there's a 1:1 relationship between
|
||||
// the _SliderRenderObjectWidget object and the _SliderState object.
|
||||
}
|
||||
|
@ -319,16 +319,16 @@ const double _kAdjustmentUnit = 0.1; // Matches iOS implementation of material s
|
|||
|
||||
class _RenderCupertinoSlider extends RenderConstrainedBox {
|
||||
_RenderCupertinoSlider({
|
||||
@required double value,
|
||||
int divisions,
|
||||
Color activeColor,
|
||||
Color thumbColor,
|
||||
Color trackColor,
|
||||
ValueChanged<double> onChanged,
|
||||
required double value,
|
||||
int? divisions,
|
||||
required Color activeColor,
|
||||
required Color thumbColor,
|
||||
required Color trackColor,
|
||||
ValueChanged<double>? onChanged,
|
||||
this.onChangeStart,
|
||||
this.onChangeEnd,
|
||||
TickerProvider vsync,
|
||||
@required TextDirection textDirection,
|
||||
required TickerProvider vsync,
|
||||
required TextDirection textDirection,
|
||||
}) : assert(value != null && value >= 0.0 && value <= 1.0),
|
||||
assert(textDirection != null),
|
||||
_value = value,
|
||||
|
@ -364,9 +364,9 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
|||
markNeedsSemanticsUpdate();
|
||||
}
|
||||
|
||||
int get divisions => _divisions;
|
||||
int _divisions;
|
||||
set divisions(int value) {
|
||||
int? get divisions => _divisions;
|
||||
int? _divisions;
|
||||
set divisions(int? value) {
|
||||
if (value == _divisions)
|
||||
return;
|
||||
_divisions = value;
|
||||
|
@ -400,9 +400,9 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
|||
markNeedsPaint();
|
||||
}
|
||||
|
||||
ValueChanged<double> get onChanged => _onChanged;
|
||||
ValueChanged<double> _onChanged;
|
||||
set onChanged(ValueChanged<double> value) {
|
||||
ValueChanged<double>? get onChanged => _onChanged;
|
||||
ValueChanged<double>? _onChanged;
|
||||
set onChanged(ValueChanged<double>? value) {
|
||||
if (value == _onChanged)
|
||||
return;
|
||||
final bool wasInteractive = isInteractive;
|
||||
|
@ -411,8 +411,8 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
|||
markNeedsSemanticsUpdate();
|
||||
}
|
||||
|
||||
ValueChanged<double> onChangeStart;
|
||||
ValueChanged<double> onChangeEnd;
|
||||
ValueChanged<double>? onChangeStart;
|
||||
ValueChanged<double>? onChangeEnd;
|
||||
|
||||
TextDirection get textDirection => _textDirection;
|
||||
TextDirection _textDirection;
|
||||
|
@ -424,15 +424,15 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
|||
markNeedsPaint();
|
||||
}
|
||||
|
||||
AnimationController _position;
|
||||
late AnimationController _position;
|
||||
|
||||
HorizontalDragGestureRecognizer _drag;
|
||||
late HorizontalDragGestureRecognizer _drag;
|
||||
double _currentDragValue = 0.0;
|
||||
|
||||
double get _discretizedCurrentDragValue {
|
||||
double dragValue = _currentDragValue.clamp(0.0, 1.0) as double;
|
||||
double dragValue = _currentDragValue.clamp(0.0, 1.0);
|
||||
if (divisions != null)
|
||||
dragValue = (dragValue * divisions).round() / divisions;
|
||||
dragValue = (dragValue * divisions!).round() / divisions!;
|
||||
return dragValue;
|
||||
}
|
||||
|
||||
|
@ -448,7 +448,7 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
|||
visualPosition = _value;
|
||||
break;
|
||||
}
|
||||
return lerpDouble(_trackLeft + CupertinoThumbPainter.radius, _trackRight - CupertinoThumbPainter.radius, visualPosition);
|
||||
return lerpDouble(_trackLeft + CupertinoThumbPainter.radius, _trackRight - CupertinoThumbPainter.radius, visualPosition)!;
|
||||
}
|
||||
|
||||
bool get isInteractive => onChanged != null;
|
||||
|
@ -458,7 +458,7 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
|||
void _handleDragUpdate(DragUpdateDetails details) {
|
||||
if (isInteractive) {
|
||||
final double extent = math.max(_kPadding, size.width - 2.0 * (_kPadding + CupertinoThumbPainter.radius));
|
||||
final double valueDelta = details.primaryDelta / extent;
|
||||
final double valueDelta = details.primaryDelta! / extent;
|
||||
switch (textDirection) {
|
||||
case TextDirection.rtl:
|
||||
_currentDragValue -= valueDelta;
|
||||
|
@ -467,7 +467,7 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
|||
_currentDragValue += valueDelta;
|
||||
break;
|
||||
}
|
||||
onChanged(_discretizedCurrentDragValue);
|
||||
onChanged!(_discretizedCurrentDragValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -476,16 +476,16 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
|||
void _startInteraction(Offset globalPosition) {
|
||||
if (isInteractive) {
|
||||
if (onChangeStart != null) {
|
||||
onChangeStart(_discretizedCurrentDragValue);
|
||||
onChangeStart!(_discretizedCurrentDragValue);
|
||||
}
|
||||
_currentDragValue = _value;
|
||||
onChanged(_discretizedCurrentDragValue);
|
||||
onChanged!(_discretizedCurrentDragValue);
|
||||
}
|
||||
}
|
||||
|
||||
void _endInteraction() {
|
||||
if (onChangeEnd != null) {
|
||||
onChangeEnd(_discretizedCurrentDragValue);
|
||||
onChangeEnd!(_discretizedCurrentDragValue);
|
||||
}
|
||||
_currentDragValue = 0.0;
|
||||
}
|
||||
|
@ -558,15 +558,15 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
|||
}
|
||||
}
|
||||
|
||||
double get _semanticActionUnit => divisions != null ? 1.0 / divisions : _kAdjustmentUnit;
|
||||
double get _semanticActionUnit => divisions != null ? 1.0 / divisions! : _kAdjustmentUnit;
|
||||
|
||||
void _increaseAction() {
|
||||
if (isInteractive)
|
||||
onChanged((value + _semanticActionUnit).clamp(0.0, 1.0) as double);
|
||||
onChanged!((value + _semanticActionUnit).clamp(0.0, 1.0));
|
||||
}
|
||||
|
||||
void _decreaseAction() {
|
||||
if (isInteractive)
|
||||
onChanged((value - _semanticActionUnit).clamp(0.0, 1.0) as double);
|
||||
onChanged!((value - _semanticActionUnit).clamp(0.0, 1.0));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// 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/painting.dart';
|
||||
|
||||
import 'colors.dart';
|
||||
|
|
|
@ -163,7 +163,7 @@ class ListWheelChildBuilderDelegate extends ListWheelChildDelegate {
|
|||
}) : assert(builder != null);
|
||||
|
||||
/// Called lazily to build children.
|
||||
final IndexedWidgetBuilder builder;
|
||||
final NullableIndexedWidgetBuilder builder;
|
||||
|
||||
/// {@template flutter.widgets.wheelList.childCount}
|
||||
/// If non-null, [childCount] is the maximum number of children that can be
|
||||
|
|
|
@ -633,7 +633,7 @@ class HeroControllerScope extends InheritedWidget {
|
|||
/// Creates a widget to host the input [controller].
|
||||
const HeroControllerScope({
|
||||
Key? key,
|
||||
this.controller,
|
||||
required HeroController this.controller,
|
||||
required Widget child,
|
||||
}) : assert(controller != null),
|
||||
super(key: key, child: child);
|
||||
|
|
Loading…
Reference in a new issue