Unverified Commit 29fae79c authored by Alexandre Ardhuin's avatar Alexandre Ardhuin Committed by GitHub

migrate some cupertino files to nullsafety (#66424)

* migrate some cupertino files to nullsafety

* address review comments
parent 707aa49e
......@@ -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/rendering.dart';
import 'package:flutter/widgets.dart';
......@@ -70,16 +68,16 @@ class CupertinoApp extends StatefulWidget {
///
/// The boolean arguments, [routes], and [navigatorObservers], must not be null.
const CupertinoApp({
Key key,
Key? key,
this.navigatorKey,
this.home,
this.theme,
this.routes = const <String, WidgetBuilder>{},
Map<String, Widget Function(BuildContext)> this.routes = const <String, WidgetBuilder>{},
this.initialRoute,
this.onGenerateRoute,
this.onGenerateInitialRoutes,
this.onUnknownRoute,
this.navigatorObservers = const <NavigatorObserver>[],
List<NavigatorObserver> this.navigatorObservers = const <NavigatorObserver>[],
this.builder,
this.title = '',
this.onGenerateTitle,
......@@ -112,10 +110,10 @@ class CupertinoApp extends StatefulWidget {
/// Creates a [CupertinoApp] that uses the [Router] instead of a [Navigator].
const CupertinoApp.router({
Key key,
Key? key,
this.routeInformationProvider,
@required this.routeInformationParser,
@required this.routerDelegate,
required RouteInformationParser<Object> this.routeInformationParser,
required RouterDelegate<Object> this.routerDelegate,
this.backButtonDispatcher,
this.theme,
this.builder,
......@@ -151,16 +149,16 @@ class CupertinoApp extends StatefulWidget {
super(key: key);
/// {@macro flutter.widgets.widgetsApp.navigatorKey}
final GlobalKey<NavigatorState> navigatorKey;
final GlobalKey<NavigatorState>? navigatorKey;
/// {@macro flutter.widgets.widgetsApp.home}
final Widget home;
final Widget? home;
/// The top-level [CupertinoTheme] styling.
///
/// A null [theme] or unspecified [theme] attributes will default to iOS
/// system values.
final CupertinoThemeData theme;
final CupertinoThemeData? theme;
/// The application's top-level routing table.
///
......@@ -170,37 +168,37 @@ class CupertinoApp extends StatefulWidget {
/// an appropriate transition, including [Hero] animations, to the new route.
///
/// {@macro flutter.widgets.widgetsApp.routes}
final Map<String, WidgetBuilder> routes;
final Map<String, WidgetBuilder>? routes;
/// {@macro flutter.widgets.widgetsApp.initialRoute}
final String initialRoute;
final String? initialRoute;
/// {@macro flutter.widgets.widgetsApp.onGenerateRoute}
final RouteFactory onGenerateRoute;
final RouteFactory? onGenerateRoute;
/// {@macro flutter.widgets.widgetsApp.onGenerateInitialRoutes}
final InitialRouteListFactory onGenerateInitialRoutes;
final InitialRouteListFactory? onGenerateInitialRoutes;
/// {@macro flutter.widgets.widgetsApp.onUnknownRoute}
final RouteFactory onUnknownRoute;
final RouteFactory? onUnknownRoute;
/// {@macro flutter.widgets.widgetsApp.navigatorObservers}
final List<NavigatorObserver> navigatorObservers;
final List<NavigatorObserver>? navigatorObservers;
/// {@macro flutter.widgets.widgetsApp.routeInformationProvider}
final RouteInformationProvider routeInformationProvider;
final RouteInformationProvider? routeInformationProvider;
/// {@macro flutter.widgets.widgetsApp.routeInformationParser}
final RouteInformationParser<Object> routeInformationParser;
final RouteInformationParser<Object>? routeInformationParser;
/// {@macro flutter.widgets.widgetsApp.routerDelegate}
final RouterDelegate<Object> routerDelegate;
final RouterDelegate<Object>? routerDelegate;
/// {@macro flutter.widgets.widgetsApp.backButtonDispatcher}
final BackButtonDispatcher backButtonDispatcher;
final BackButtonDispatcher? backButtonDispatcher;
/// {@macro flutter.widgets.widgetsApp.builder}
final TransitionBuilder builder;
final TransitionBuilder? builder;
/// {@macro flutter.widgets.widgetsApp.title}
///
......@@ -210,26 +208,26 @@ class CupertinoApp extends StatefulWidget {
/// {@macro flutter.widgets.widgetsApp.onGenerateTitle}
///
/// This value is passed unmodified to [WidgetsApp.onGenerateTitle].
final GenerateAppTitle onGenerateTitle;
final GenerateAppTitle? onGenerateTitle;
/// {@macro flutter.widgets.widgetsApp.color}
final Color color;
final Color? color;
/// {@macro flutter.widgets.widgetsApp.locale}
final Locale locale;
final Locale? locale;
/// {@macro flutter.widgets.widgetsApp.localizationsDelegates}
final Iterable<LocalizationsDelegate<dynamic>> localizationsDelegates;
final Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates;
/// {@macro flutter.widgets.widgetsApp.localeListResolutionCallback}
///
/// This callback is passed along to the [WidgetsApp] built by this widget.
final LocaleListResolutionCallback localeListResolutionCallback;
final LocaleListResolutionCallback? localeListResolutionCallback;
/// {@macro flutter.widgets.widgetsApp.localeResolutionCallback}
///
/// This callback is passed along to the [WidgetsApp] built by this widget.
final LocaleResolutionCallback localeResolutionCallback;
final LocaleResolutionCallback? localeResolutionCallback;
/// {@macro flutter.widgets.widgetsApp.supportedLocales}
///
......@@ -282,7 +280,7 @@ class CupertinoApp extends StatefulWidget {
/// ```
/// {@end-tool}
/// {@macro flutter.widgets.widgetsApp.shortcuts.seeAlso}
final Map<LogicalKeySet, Intent> shortcuts;
final Map<LogicalKeySet, Intent>? shortcuts;
/// {@macro flutter.widgets.widgetsApp.actions}
/// {@tool snippet}
......@@ -315,7 +313,7 @@ class CupertinoApp extends StatefulWidget {
/// ```
/// {@end-tool}
/// {@macro flutter.widgets.widgetsApp.actions.seeAlso}
final Map<Type, Action<Intent>> actions;
final Map<Type, Action<Intent>>? actions;
@override
_CupertinoAppState createState() => _CupertinoAppState();
......@@ -341,7 +339,7 @@ class _AlwaysCupertinoScrollBehavior extends ScrollBehavior {
}
class _CupertinoAppState extends State<CupertinoApp> {
HeroController _heroController;
late HeroController _heroController;
bool get _usesRouter => widget.routerDelegate != null;
@override
......@@ -357,7 +355,7 @@ class _CupertinoAppState extends State<CupertinoApp> {
// _CupertinoLocalizationsDelegate.
Iterable<LocalizationsDelegate<dynamic>> get _localizationsDelegates sync* {
if (widget.localizationsDelegates != null)
yield* widget.localizationsDelegates;
yield* widget.localizationsDelegates!;
yield DefaultCupertinoLocalizations.delegate;
}
......@@ -375,14 +373,14 @@ class _CupertinoAppState extends State<CupertinoApp> {
WidgetsApp _buildWidgetApp(BuildContext context) {
final CupertinoThemeData effectiveThemeData = CupertinoTheme.of(context);
final Color color = CupertinoDynamicColor.resolve(widget.color ?? effectiveThemeData.primaryColor, context);
final Color color = CupertinoDynamicColor.resolve(widget.color ?? effectiveThemeData.primaryColor, context)!;
if (_usesRouter) {
return WidgetsApp.router(
key: GlobalObjectKey(this),
routeInformationProvider: widget.routeInformationProvider,
routeInformationParser: widget.routeInformationParser,
routerDelegate: widget.routerDelegate,
routeInformationParser: widget.routeInformationParser!,
routerDelegate: widget.routerDelegate!,
backButtonDispatcher: widget.backButtonDispatcher,
builder: widget.builder,
title: widget.title,
......@@ -407,12 +405,12 @@ class _CupertinoAppState extends State<CupertinoApp> {
return WidgetsApp(
key: GlobalObjectKey(this),
navigatorKey: widget.navigatorKey,
navigatorObservers: widget.navigatorObservers,
navigatorObservers: widget.navigatorObservers!,
pageRouteBuilder: <T>(RouteSettings settings, WidgetBuilder builder) {
return CupertinoPageRoute<T>(settings: settings, builder: builder);
},
home: widget.home,
routes: widget.routes,
routes: widget.routes!,
initialRoute: widget.initialRoute,
onGenerateRoute: widget.onGenerateRoute,
onGenerateInitialRoutes: widget.onGenerateInitialRoutes,
......
......@@ -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:ui' show ImageFilter;
import 'package:flutter/widgets.dart';
......@@ -53,8 +51,8 @@ const Color _kDefaultTabBarInactiveColor = CupertinoColors.inactiveGray;
class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
/// Creates a tab bar in the iOS style.
const CupertinoTabBar({
Key key,
@required this.items,
Key? key,
required this.items,
this.onTap,
this.currentIndex = 0,
this.backgroundColor,
......@@ -89,7 +87,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
/// The widget creating the bottom navigation bar needs to keep track of the
/// current index and call `setState` to rebuild it with the newly provided
/// index.
final ValueChanged<int> onTap;
final ValueChanged<int>? onTap;
/// The index into [items] of the current active item.
///
......@@ -102,13 +100,13 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
/// behind it.
///
/// Defaults to [CupertinoTheme]'s `barBackgroundColor` when null.
final Color backgroundColor;
final Color? backgroundColor;
/// The foreground color of the icon and title for the [BottomNavigationBarItem]
/// of the selected tab.
///
/// Defaults to [CupertinoTheme]'s `primaryColor` if null.
final Color activeColor;
final Color? activeColor;
/// The foreground color of the icon and title for the [BottomNavigationBarItem]s
/// in the unselected state.
......@@ -129,7 +127,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
/// The border of the [CupertinoTabBar].
///
/// The default value is a one physical pixel top border with grey color.
final Border border;
final Border? border;
@override
Size get preferredSize => const Size.fromHeight(_kTabBarHeight);
......@@ -139,14 +137,15 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
bool opaque(BuildContext context) {
final Color backgroundColor =
this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor;
return CupertinoDynamicColor.resolve(backgroundColor, context).alpha == 0xFF;
return CupertinoDynamicColor.resolve(backgroundColor, context)!.alpha == 0xFF;
}
@override
Widget build(BuildContext context) {
final double bottomPadding = MediaQuery.of(context).padding.bottom;
assert(debugCheckHasMediaQuery(context));
final double bottomPadding = MediaQuery.of(context)!.padding.bottom;
final Color backgroundColor = CupertinoDynamicColor.resolve(
final Color? backgroundColor = CupertinoDynamicColor.resolve(
this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor,
context,
);
......@@ -158,16 +157,16 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
}
// Return the border as is when it's a subclass.
final Border resolvedBorder = border == null || border.runtimeType != Border
final Border? resolvedBorder = border == null || border.runtimeType != Border
? border
: Border(
top: resolveBorderSide(border.top),
left: resolveBorderSide(border.left),
bottom: resolveBorderSide(border.bottom),
right: resolveBorderSide(border.right),
top: resolveBorderSide(border!.top),
left: resolveBorderSide(border!.left),
bottom: resolveBorderSide(border!.bottom),
right: resolveBorderSide(border!.right),
);
final Color inactive = CupertinoDynamicColor.resolve(inactiveColor, context);
final Color? inactive = CupertinoDynamicColor.resolve(inactiveColor, context);
Widget result = DecoratedBox(
decoration: BoxDecoration(
border: resolvedBorder,
......@@ -210,7 +209,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
List<Widget> _buildTabItems(BuildContext context) {
final List<Widget> result = <Widget>[];
final CupertinoLocalizations localizations = CupertinoLocalizations.of(context);
final CupertinoLocalizations? localizations = CupertinoLocalizations.of(context);
assert(
localizations != null,
'CupertinoTabBar requires a Localizations parent in order to provide an '
......@@ -227,13 +226,13 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
Expanded(
child: Semantics(
selected: active,
hint: localizations.tabSemanticsLabel(
hint: localizations!.tabSemanticsLabel(
tabIndex: index + 1,
tabCount: items.length,
),
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: onTap == null ? null : () { onTap(index); },
onTap: onTap == null ? null : () { onTap!(index); },
child: Padding(
padding: const EdgeInsets.only(bottom: 4.0),
child: Column(
......@@ -257,17 +256,17 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
Expanded(
child: Center(child: active ? item.activeIcon : item.icon),
),
if (item.title != null) item.title,
if (item.label != null) Text(item.label),
if (item.title != null) item.title!,
if (item.label != null) Text(item.label!),
];
}
/// Change the active tab item's icon and title colors to active.
Widget _wrapActiveItem(BuildContext context, Widget item, { @required bool active }) {
Widget _wrapActiveItem(BuildContext context, Widget item, { required bool active }) {
if (!active)
return item;
final Color activeColor = CupertinoDynamicColor.resolve(
final Color? activeColor = CupertinoDynamicColor.resolve(
this.activeColor ?? CupertinoTheme.of(context).primaryColor,
context,
);
......@@ -283,15 +282,15 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
/// Create a clone of the current [CupertinoTabBar] but with provided
/// parameters overridden.
CupertinoTabBar copyWith({
Key key,
List<BottomNavigationBarItem> items,
Color backgroundColor,
Color activeColor,
Color inactiveColor,
double iconSize,
Border border,
int currentIndex,
ValueChanged<int> onTap,
Key? key,
List<BottomNavigationBarItem>? items,
Color? backgroundColor,
Color? activeColor,
Color? inactiveColor,
double? iconSize,
Border? border,
int? currentIndex,
ValueChanged<int>? onTap,
}) {
return CupertinoTabBar(
key: key ?? this.key,
......
......@@ -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/rendering.dart';
import 'package:flutter/widgets.dart';
import 'colors.dart';
......@@ -16,8 +14,8 @@ import 'colors.dart';
class CupertinoContextMenuAction extends StatefulWidget {
/// Construct a CupertinoContextMenuAction.
const CupertinoContextMenuAction({
Key key,
@required this.child,
Key? key,
required this.child,
this.isDefaultAction = false,
this.isDestructiveAction = false,
this.onPressed,
......@@ -39,13 +37,13 @@ class CupertinoContextMenuAction extends StatefulWidget {
final bool isDestructiveAction;
/// Called when the action is pressed.
final VoidCallback onPressed;
final VoidCallback? onPressed;
/// An optional icon to display to the right of the child.
///
/// Will be colored in the same way as the [TextStyle] used for [child] (for
/// example, if using [isDestructiveAction]).
final IconData trailingIcon;
final IconData? trailingIcon;
@override
_CupertinoContextMenuActionState createState() => _CupertinoContextMenuActionState();
......
......@@ -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';
......@@ -156,7 +154,7 @@ abstract class CupertinoLocalizations {
/// there are, e.g. 'tab, 1 of 2' in United States English.
///
/// `tabIndex` and `tabCount` must be greater than or equal to one.
String tabSemanticsLabel({int tabIndex, int tabCount});
String tabSemanticsLabel({required int tabIndex, required int tabCount});
/// Hour that is shown in [CupertinoTimerPicker] corresponding to
/// the given hour value.
......@@ -241,7 +239,7 @@ abstract class CupertinoLocalizations {
/// ```dart
/// CupertinoLocalizations.of(context).anteMeridiemAbbreviation;
/// ```
static CupertinoLocalizations of(BuildContext context) {
static CupertinoLocalizations? of(BuildContext context) {
return Localizations.of<CupertinoLocalizations>(context, CupertinoLocalizations);
}
}
......@@ -364,7 +362,7 @@ class DefaultCupertinoLocalizations implements CupertinoLocalizations {
String get alertDialogLabel => 'Alert';
@override
String tabSemanticsLabel({int tabIndex, int tabCount}) {
String tabSemanticsLabel({required int tabIndex, required int tabCount}) {
assert(tabIndex >= 1);
assert(tabCount >= 1);
return 'Tab $tabIndex of $tabCount';
......
......@@ -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:async';
import 'package:flutter/gestures.dart';
......@@ -56,14 +54,14 @@ class CupertinoScrollbar extends StatefulWidget {
/// The [child] should be a source of [ScrollNotification] notifications,
/// typically a [Scrollable] widget.
const CupertinoScrollbar({
Key key,
Key? key,
this.controller,
this.isAlwaysShown = false,
this.thickness = defaultThickness,
this.thicknessWhileDragging = defaultThicknessWhileDragging,
this.radius = defaultRadius,
this.radiusWhileDragging = defaultRadiusWhileDragging,
@required this.child,
required this.child,
}) : assert(thickness != null),
assert(thickness < double.infinity),
assert(thicknessWhileDragging != null),
......@@ -145,7 +143,7 @@ class CupertinoScrollbar extends StatefulWidget {
/// ```
/// {@end-tool}
/// {@endtemplate}
final ScrollController controller;
final ScrollController? controller;
/// {@template flutter.cupertino.cupertinoScrollbar.isAlwaysShown}
/// Indicates whether the [Scrollbar] should always be visible.
......@@ -237,25 +235,25 @@ class CupertinoScrollbar extends StatefulWidget {
class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProviderStateMixin {
final GlobalKey _customPaintKey = GlobalKey();
ScrollbarPainter _painter;
ScrollbarPainter? _painter;
AnimationController _fadeoutAnimationController;
Animation<double> _fadeoutOpacityAnimation;
AnimationController _thicknessAnimationController;
Timer _fadeoutTimer;
double _dragScrollbarPositionY;
Drag _drag;
late AnimationController _fadeoutAnimationController;
late Animation<double> _fadeoutOpacityAnimation;
late AnimationController _thicknessAnimationController;
Timer? _fadeoutTimer;
double? _dragScrollbarPositionY;
Drag? _drag;
double get _thickness {
return widget.thickness + _thicknessAnimationController.value * (widget.thicknessWhileDragging - widget.thickness);
}
Radius get _radius {
return Radius.lerp(widget.radius, widget.radiusWhileDragging, _thicknessAnimationController.value);
return Radius.lerp(widget.radius, widget.radiusWhileDragging, _thicknessAnimationController.value)!;
}
ScrollController _currentController;
ScrollController get _controller =>
ScrollController? _currentController;
ScrollController? get _controller =>
widget.controller ?? PrimaryScrollController.of(context);
@override
......@@ -274,7 +272,7 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
duration: _kScrollbarResizeDuration,
);
_thicknessAnimationController.addListener(() {
_painter.updateThickness(_thickness, _radius);
_painter!.updateThickness(_thickness, _radius);
});
}
......@@ -284,10 +282,10 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
if (_painter == null) {
_painter = _buildCupertinoScrollbarPainter(context);
} else {
_painter
..textDirection = Directionality.of(context)
..color = CupertinoDynamicColor.resolve(_kScrollbarColor, context)
..padding = MediaQuery.of(context).padding;
_painter!
..textDirection = Directionality.of(context)!
..color = CupertinoDynamicColor.resolve(_kScrollbarColor, context)!
..padding = MediaQuery.of(context)!.padding;
}
_triggerScrollbar();
}
......@@ -296,7 +294,7 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
void didUpdateWidget(CupertinoScrollbar oldWidget) {
super.didUpdateWidget(oldWidget);
assert(_painter != null);
_painter.updateThickness(_thickness, _radius);
_painter!.updateThickness(_thickness, _radius);
if (widget.isAlwaysShown != oldWidget.isAlwaysShown) {
if (widget.isAlwaysShown == true) {
_triggerScrollbar();
......@@ -310,14 +308,14 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
/// Returns a [ScrollbarPainter] visually styled like the iOS scrollbar.
ScrollbarPainter _buildCupertinoScrollbarPainter(BuildContext context) {
return ScrollbarPainter(
color: CupertinoDynamicColor.resolve(_kScrollbarColor, context),
textDirection: Directionality.of(context),
color: CupertinoDynamicColor.resolve(_kScrollbarColor, context)!,
textDirection: Directionality.of(context)!,
thickness: _thickness,
fadeoutOpacityAnimation: _fadeoutOpacityAnimation,
mainAxisMargin: _kScrollbarMainAxisMargin,
crossAxisMargin: _kScrollbarCrossAxisMargin,
radius: _radius,
padding: MediaQuery.of(context).padding,
padding: MediaQuery.of(context)!.padding,
minLength: _kScrollbarMinLength,
minOverscrollLength: _kScrollbarMinOverscrollLength,
);
......@@ -327,10 +325,10 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
// show immediately when isAlwaysShown is true. A scroll event is required in
// order to paint the thumb.
void _triggerScrollbar() {
WidgetsBinding.instance.addPostFrameCallback((Duration duration) {
WidgetsBinding.instance!.addPostFrameCallback((Duration duration) {
if (widget.isAlwaysShown) {
_fadeoutTimer?.cancel();
widget.controller.position.didUpdateScrollPositionBy(0);
widget.controller!.position.didUpdateScrollPositionBy(0);
}
});
}
......@@ -342,18 +340,18 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
// Convert primaryDelta, the amount that the scrollbar moved since the last
// time _dragScrollbar was called, into the coordinate space of the scroll
// position, and create/update the drag event with that position.
final double scrollOffsetLocal = _painter.getTrackToScroll(primaryDelta);
final double scrollOffsetGlobal = scrollOffsetLocal + _currentController.position.pixels;
final double scrollOffsetLocal = _painter!.getTrackToScroll(primaryDelta);
final double scrollOffsetGlobal = scrollOffsetLocal + _currentController!.position.pixels;
if (_drag == null) {
_drag = _currentController.position.drag(
_drag = _currentController!.position.drag(
DragStartDetails(
globalPosition: Offset(0.0, scrollOffsetGlobal),
),
() {},
);
} else {
_drag.update(DragUpdateDetails(
_drag!.update(DragUpdateDetails(
globalPosition: Offset(0.0, scrollOffsetGlobal),
delta: Offset(0.0, -scrollOffsetLocal),
primaryDelta: -scrollOffsetLocal,
......@@ -373,7 +371,7 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
bool _checkVertical() {
try {
return _currentController.position.axis == Axis.vertical;
return _currentController!.position.axis == Axis.vertical;
} catch (_) {
// Ignore the gesture if we cannot determine the direction.
return false;
......@@ -410,7 +408,7 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
if (!_checkVertical()) {
return;
}
_dragScrollbar(details.localPosition.dy - _dragScrollbarPositionY);
_dragScrollbar(details.localPosition.dy - _dragScrollbarPositionY!);
_dragScrollbarPositionY = details.localPosition.dy;
}
......@@ -430,7 +428,7 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
_startFadeoutTimer();
_thicknessAnimationController.reverse();
_dragScrollbarPositionY = null;
final double scrollVelocityY = _painter.getTrackToScroll(trackVelocityY);
final double scrollVelocityY = _painter!.getTrackToScroll(trackVelocityY);
_drag?.end(DragEndDetails(
primaryVelocity: -scrollVelocityY,
velocity: Velocity(
......@@ -457,7 +455,7 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
}
_fadeoutTimer?.cancel();
_painter.update(notification.metrics, notification.metrics.axisDirection);
_painter!.update(notification.metrics, notification.metrics.axisDirection);
} else if (notification is ScrollEndNotification) {
// On iOS, the scrollbar can only go away once the user lifted the finger.
if (_dragScrollbarPositionY == null) {
......@@ -496,7 +494,7 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
_fadeoutAnimationController.dispose();
_thicknessAnimationController.dispose();
_fadeoutTimer?.cancel();
_painter.dispose();
_painter!.dispose();
super.dispose();
}
......@@ -522,10 +520,10 @@ class _CupertinoScrollbarState extends State<CupertinoScrollbar> with TickerProv
// thumb and ignores everything else.
class _ThumbPressGestureRecognizer extends LongPressGestureRecognizer {
_ThumbPressGestureRecognizer({
double postAcceptSlopTolerance,
PointerDeviceKind kind,
Object debugOwner,
GlobalKey customPaintKey,
double? postAcceptSlopTolerance,
PointerDeviceKind? kind,
required Object debugOwner,
required GlobalKey customPaintKey,
}) : _customPaintKey = customPaintKey,
super(
postAcceptSlopTolerance: postAcceptSlopTolerance,
......@@ -552,9 +550,9 @@ bool _hitTestInteractive(GlobalKey customPaintKey, Offset offset) {
if (customPaintKey.currentContext == null) {
return false;
}
final CustomPaint customPaint = customPaintKey.currentContext.widget as CustomPaint;
final CustomPaint customPaint = customPaintKey.currentContext!.widget as CustomPaint;
final ScrollbarPainter painter = customPaint.foregroundPainter as ScrollbarPainter;
final RenderBox renderBox = customPaintKey.currentContext.findRenderObject() as RenderBox;
final RenderBox renderBox = customPaintKey.currentContext!.findRenderObject() as RenderBox;
final Offset localOffset = renderBox.globalToLocal(offset);
return painter.hitTestInteractive(localOffset);
}
......@@ -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:ui' show lerpDouble;
import 'package:flutter/foundation.dart';
......@@ -58,9 +56,9 @@ class CupertinoSwitch extends StatefulWidget {
/// The [value] parameter must not be null.
/// The [dragStartBehavior] parameter defaults to [DragStartBehavior.start] and must not be null.
const CupertinoSwitch({
Key key,
@required this.value,
@required this.onChanged,
Key? key,
required this.value,
required this.onChanged,
this.activeColor,
this.trackColor,
this.dragStartBehavior = DragStartBehavior.start,
......@@ -95,18 +93,18 @@ class CupertinoSwitch extends StatefulWidget {
/// },
/// )
/// ```
final ValueChanged<bool> onChanged;
final ValueChanged<bool>? onChanged;
/// The color to use when this switch is on.
///
/// Defaults to [CupertinoColors.systemGreen] when null and ignores
/// the [CupertinoTheme] in accordance to native iOS behavior.
final Color activeColor;
final Color? activeColor;
/// The color to use for the background when the switch is off.
///
/// Defaults to [CupertinoColors.secondarySystemFill] when null.
final Color trackColor;
final Color? trackColor;
/// {@template flutter.cupertino.switch.dragStartBehavior}
/// Determines the way that drag start behavior is handled.
......@@ -142,14 +140,14 @@ class CupertinoSwitch extends StatefulWidget {
}
class _CupertinoSwitchState extends State<CupertinoSwitch> with TickerProviderStateMixin {
TapGestureRecognizer _tap;
HorizontalDragGestureRecognizer _drag;
late TapGestureRecognizer _tap;
late HorizontalDragGestureRecognizer _drag;
AnimationController _positionController;
CurvedAnimation position;
late AnimationController _positionController;
late CurvedAnimation position;
AnimationController _reactionController;
Animation<double> _reaction;
late AnimationController _reactionController;
late Animation<double> _reaction;
bool get isInteractive => widget.onChanged != null;
......@@ -209,8 +207,8 @@ class _CupertinoSwitchState extends State<CupertinoSwitch> with TickerProviderSt
void _resumePositionAnimation({ bool isLinear = true }) {
needsPositionAnimation = false;
position
..curve = isLinear ? null : Curves.ease
..reverseCurve = isLinear ? null : Curves.ease.flipped;
..curve = isLinear ? Curves.linear : Curves.ease
..reverseCurve = isLinear ? Curves.linear : Curves.ease.flipped;
if (widget.value)
_positionController.forward();
else
......@@ -225,7 +223,7 @@ class _CupertinoSwitchState extends State<CupertinoSwitch> with TickerProviderSt
void _handleTap() {
if (isInteractive) {
widget.onChanged(!widget.value);
widget.onChanged!(!widget.value);
_emitVibration();
}
}
......@@ -253,10 +251,10 @@ class _CupertinoSwitchState extends State<CupertinoSwitch> with TickerProviderSt
void _handleDragUpdate(DragUpdateDetails details) {
if (isInteractive) {
position
..curve = null
..reverseCurve = null;
final double delta = details.primaryDelta / _kTrackInnerLength;
switch (Directionality.of(context)) {
..curve = Curves.linear
..reverseCurve = Curves.linear;
final double delta = details.primaryDelta! / _kTrackInnerLength;
switch (Directionality.of(context)!) {
case TextDirection.rtl:
_positionController.value -= delta;
break;
......@@ -272,7 +270,7 @@ class _CupertinoSwitchState extends State<CupertinoSwitch> with TickerProviderSt
setState(() { needsPositionAnimation = true; });
// Call onChanged when the user's intent to change value is clear.
if (position.value >= 0.5 != widget.value)
widget.onChanged(!widget.value);
widget.onChanged!(!widget.value);
_reactionController.reverse();
}
......@@ -301,10 +299,10 @@ class _CupertinoSwitchState extends State<CupertinoSwitch> with TickerProviderSt
activeColor: CupertinoDynamicColor.resolve(
widget.activeColor ?? CupertinoColors.systemGreen,
context,
),
trackColor: CupertinoDynamicColor.resolve(widget.trackColor ?? CupertinoColors.secondarySystemFill, context),
)!,
trackColor: CupertinoDynamicColor.resolve(widget.trackColor ?? CupertinoColors.secondarySystemFill, context)!,
onChanged: widget.onChanged,
textDirection: Directionality.of(context),
textDirection: Directionality.of(context)!,
state: this,
),
);
......@@ -323,19 +321,19 @@ class _CupertinoSwitchState extends State<CupertinoSwitch> with TickerProviderSt
class _CupertinoSwitchRenderObjectWidget extends LeafRenderObjectWidget {
const _CupertinoSwitchRenderObjectWidget({
Key key,
this.value,
this.activeColor,
this.trackColor,
this.onChanged,
this.textDirection,
this.state,
Key? key,
required this.value,
required this.activeColor,
required this.trackColor,
required this.onChanged,
required this.textDirection,
required this.state,
}) : super(key: key);
final bool value;
final Color activeColor;
final Color trackColor;
final ValueChanged<bool> onChanged;
final ValueChanged<bool>? onChanged;
final _CupertinoSwitchState state;
final TextDirection textDirection;
......@@ -378,12 +376,12 @@ const Duration _kToggleDuration = Duration(milliseconds: 200);
class _RenderCupertinoSwitch extends RenderConstrainedBox {
_RenderCupertinoSwitch({
@required bool value,
@required Color activeColor,
@required Color trackColor,
ValueChanged<bool> onChanged,
@required TextDirection textDirection,
@required _CupertinoSwitchState state,
required bool value,
required Color activeColor,
required Color trackColor,
ValueChanged<bool>? onChanged,
required TextDirection textDirection,
required _CupertinoSwitchState state,
}) : assert(value != null),
assert(activeColor != null),
assert(state != null),
......@@ -430,9 +428,9 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
markNeedsPaint();
}
ValueChanged<bool> get onChanged => _onChanged;
ValueChanged<bool> _onChanged;
set onChanged(ValueChanged<bool> value) {
ValueChanged<bool>? get onChanged => _onChanged;
ValueChanged<bool>? _onChanged;
set onChanged(ValueChanged<bool>? value) {
if (value == _onChanged)
return;
final bool wasInteractive = isInteractive;
......@@ -496,7 +494,7 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
}
final Paint paint = Paint()
..color = Color.lerp(trackColor, activeColor, currentValue);
..color = Color.lerp(trackColor, activeColor, currentValue)!;
final Rect trackRect = Rect.fromLTWH(
offset.dx + (size.width - _kTrackWidth) / 2.0,
......@@ -512,12 +510,12 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
trackRect.left + _kTrackInnerStart - CupertinoThumbPainter.radius,
trackRect.left + _kTrackInnerEnd - CupertinoThumbPainter.radius - currentThumbExtension,
visualPosition,
);
)!;
final double thumbRight = lerpDouble(
trackRect.left + _kTrackInnerStart + CupertinoThumbPainter.radius + currentThumbExtension,
trackRect.left + _kTrackInnerEnd + CupertinoThumbPainter.radius,
visualPosition,
);
)!;
final double thumbCenterY = offset.dy + size.height / 2.0;
final Rect thumbBounds = Rect.fromLTRB(
thumbLeft,
......
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