Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to null safety #5

Merged
merged 2 commits into from
Feb 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.4.0 - 2021-02-27

* Migrated to null safety
## 0.3.0 - 2020-08-07

* Added splash radius field
Expand Down
5 changes: 3 additions & 2 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1

environment:
sdk: ">=2.7.0 <3.0.0"
sdk: ">=2.12.0-0 <3.0.0"
flutter: '>=1.22.0'

dependencies:
flutter:
Expand All @@ -29,7 +30,7 @@ dependencies:

# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.3
cupertino_icons: ^1.0.2

dev_dependencies:
flutter_test:
Expand Down
168 changes: 86 additions & 82 deletions lib/animated_icon_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'dart:math' as math;

class AnimatedIconButton extends StatefulWidget {
/// The size of the [AnimatedIconButton].
final double size;
final double? size;

/// The icon of the [AnimatedIconButton] when button is not pressed.
final Icon startIcon;
Expand All @@ -18,30 +18,30 @@ class AnimatedIconButton extends StatefulWidget {
/// If an [AnimationController] is specified, [Duration] must be null
/// in order to prevent an asynchronous animation. The [Duration] used will
/// be the one defined on [AnimationController]
final Duration duration;
final Duration? duration;

/// 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 Function onPressed;
final Function? onPressed;

/// The color for the button's icon when it has the input focus.
///
/// Defaults to [ThemeData.focusColor] of the ambient theme.
final Color focusColor;
final Color? focusColor;

/// The color for the button's icon when a pointer is hovering over it.
///
/// Defaults to [ThemeData.hoverColor] of the ambient theme.
final Color hoverColor;
final Color? hoverColor;

/// The secondary color of the button when the button is in the down (pressed)
/// state. The highlight color is represented as a solid color that is overlaid over the
/// button color (if any). If the highlight color has transparency, the button color
/// will show through. The highlight fades in quickly as the button is held down.
///
/// Defaults to the Theme's highlight color, [ThemeData.highlightColor].
final Color highlightColor;
final Color? highlightColor;

/// The primary color of the button when the button is in the down (pressed) state.
/// The splash is represented as a circular overlay that appears above the
Expand All @@ -51,16 +51,16 @@ class AnimatedIconButton extends StatefulWidget {
/// color has transparency then the highlight and button color will show through.
///
/// Defaults to the Theme's splash color, [ThemeData.splashColor].
final Color splashColor;
final Color? splashColor;

/// The color to use for the icon inside the button, if the icon is disabled.
/// Defaults to the [ThemeData.disabledColor] of the current [Theme].
///
/// The icon is disabled if [onPressed] is null.
final Color disabledColor;
final Color? disabledColor;

/// {@macro flutter.widgets.Focus.focusNode}
final FocusNode focusNode;
final FocusNode? focusNode;

/// {@macro flutter.widgets.Focus.autofocus}
final bool autofocus;
Expand All @@ -79,7 +79,7 @@ class AnimatedIconButton extends StatefulWidget {
///
/// This text is displayed when the user long-presses on the button and is
/// used for accessibility.
final String tooltip;
final String? tooltip;

/// Optional size constraints for the button.
///
Expand All @@ -99,7 +99,7 @@ class AnimatedIconButton extends StatefulWidget {
///
/// The visual density uses the [visualDensity] parameter if specified,
/// and `Theme.of(context).visualDensity` otherwise.
final BoxConstraints constraints;
final BoxConstraints? constraints;

/// Defines how compact the icon button's layout will be.
///
Expand All @@ -109,13 +109,13 @@ class AnimatedIconButton extends StatefulWidget {
///
/// * [ThemeData.visualDensity], which specifies the [density] for all widgets
/// within a [Theme].
final VisualDensity visualDensity;
final VisualDensity? visualDensity;

/// The padding around the button's icon. The entire padded icon will react
/// to input gestures.
///
/// This property must not be null. It defaults to 8.0 padding on all sides.
final EdgeInsets padding;
final EdgeInsets? padding;

/// Defines how the icon is positioned within the IconButton.
///
Expand All @@ -127,50 +127,50 @@ class AnimatedIconButton extends StatefulWidget {
/// specify an [AlignmentGeometry].
/// * [AlignmentDirectional], like [Alignment] for specifying alignments
/// relative to text direction.
final Alignment alignment;
final Alignment? alignment;

/// The background [Color] of the [AnimatedIconButton] when button is not pressed.
final Color startBackgroundColor;
final Color? startBackgroundColor;

/// The background [Color] of the [AnimatedIconButton] when button is pressed.
final Color endBackgroundColor;
final Color? endBackgroundColor;

/// The custom [AnimationController] of the [AnimatedIconButton].
///
/// When not specified the [AnimatedIconButton] will change it's icons and
/// background color whenever [AnimatedIconButton] is pressed.
final AnimationController animationController;
final AnimationController? animationController;

/// The splash radius.
///
/// If null, default splash radius of [Material.defaultSplashRadius] is used.
/// Field of IconButton
final double splashRadius;
final double? splashRadius;

/// The callback that is called when
/// the button animation is completed in reverse state
final Function() onReverse;
final Function()? onReverse;

/// The callback that is called when
/// the button animation is completed in forvard state
final Function() onForvard;
final Function()? onForvard;

AnimatedIconButton({
Key key,
Key? key,
this.size,
@required this.startIcon,
@required this.endIcon,
@required this.onPressed,
required this.startIcon,
required this.endIcon,
required this.onPressed,
this.focusColor,
this.hoverColor,
this.highlightColor,
this.splashColor,
this.disabledColor,
this.duration,
this.focusNode,
this.autofocus,
this.autofocus = false,
this.tooltip,
this.enableFeedback,
this.enableFeedback = true,
this.constraints,
this.visualDensity,
this.padding,
Expand Down Expand Up @@ -239,38 +239,38 @@ class _AnimatedIconButtonState extends State<AnimatedIconButton>
this.onReverse,
this.onForvard,
});
final double size;
final Icon startIcon;
final Icon endIcon;
final Color startBackgroundColor;
final Color endBackgroundColor;
Duration duration;
final Function onPressed;
final Color focusColor;
final Color hoverColor;
final Color highlightColor;
final Color splashColor;
final Color disabledColor;
final FocusNode focusNode;
final bool autofocus;
final bool enableFeedback;
final String tooltip;
final BoxConstraints constraints;
final VisualDensity visualDensity;
final EdgeInsets padding;
final Alignment alignment;
final AnimationController animationController;
final double splashRadius;
final Function() onReverse;
final Function() onForvard;

bool hasCustomAnimationController;
Icon nowIcon;
Color nowBackgroundColor;
double? size;
Icon? startIcon;
Icon? endIcon;
Color? startBackgroundColor;
Color? endBackgroundColor;
Duration? duration;
Function? onPressed;
Color? focusColor;
Color? hoverColor;
Color? highlightColor;
Color? splashColor;
Color? disabledColor;
FocusNode? focusNode;
bool autofocus;
bool enableFeedback;
String? tooltip;
BoxConstraints? constraints;
VisualDensity? visualDensity;
EdgeInsets? padding;
Alignment? alignment;
AnimationController? animationController;
double? splashRadius;
Function()? onReverse;
Function()? onForvard;

late bool hasCustomAnimationController;
Icon? nowIcon;
Color? nowBackgroundColor;
bool isIconAnimated = false;
AnimationController _arrowAnimationController;
Animation _arrowAnimation;
AnimationStatus _lastStatus;
late AnimationController _arrowAnimationController;
late Animation _arrowAnimation;
AnimationStatus? _lastStatus;
static const Duration defaultDuration = Duration(milliseconds: 200);

@override
Expand All @@ -280,11 +280,11 @@ class _AnimatedIconButtonState extends State<AnimatedIconButton>
if (hasCustomAnimationController) {
assert(duration == null,
'Duration must be null when defining an animationController');
duration = animationController.duration;
duration = animationController!.duration;
}

_arrowAnimationController = hasCustomAnimationController
? animationController
? animationController!
: AnimationController(vsync: this, duration: duration);

if (hasCustomAnimationController) _addStatusListener();
Expand Down Expand Up @@ -316,17 +316,17 @@ class _AnimatedIconButtonState extends State<AnimatedIconButton>
});
}

void _changeIcon() async {
var animationTime = duration.inMilliseconds;
_changeIcon() async {
var animationTime = duration!.inMilliseconds;
var halfDuration = Duration(milliseconds: animationTime ~/ 2);
await Future.delayed(halfDuration);
setState(() {
nowIcon = nowIcon == startIcon ? endIcon : startIcon;
});
}

void _changeBackgroundColor() async {
var animationTime = duration.inMilliseconds;
_changeBackgroundColor() async {
var animationTime = duration!.inMilliseconds;
var halfDuration = Duration(milliseconds: animationTime ~/ 2);
await Future.delayed(halfDuration);
setState(() {
Expand All @@ -337,15 +337,11 @@ class _AnimatedIconButtonState extends State<AnimatedIconButton>
}

void _onReverse() {
if (onReverse != null) {
onReverse();
}
onReverse?.call();
}

void _onForvard() {
if (onForvard != null) {
onForvard();
}
onForvard?.call();
}

void _runControllerMethods() {
Expand All @@ -359,7 +355,7 @@ class _AnimatedIconButtonState extends State<AnimatedIconButton>
}

void _onPressed() {
onPressed();
onPressed?.call();
if (!hasCustomAnimationController) {
_changeIcon();
_changeBackgroundColor();
Expand All @@ -381,25 +377,33 @@ class _AnimatedIconButtonState extends State<AnimatedIconButton>
IconButton buildIconButton() {
return IconButton(
iconSize: size ?? 30,
onPressed: () => _onPressed(),
onPressed: hasCustomAnimationController
? onPressed as void Function()?
: () {
onPressed!();
_changeIcon();
_changeBackgroundColor();
_arrowAnimationController.isCompleted
? _arrowAnimationController.reverse().then((_) => _)
: _arrowAnimationController.forward().then((_) => _);
},
icon: AnimatedBuilder(
animation: _arrowAnimationController,
builder: (BuildContext context, Widget child) {
return Transform.rotate(
angle: _arrowAnimation.value * 2.0 * math.pi,
child: child,
);
},
child: nowIcon,
),
animation: _arrowAnimationController,
builder: (BuildContext context, Widget? child) {
return Transform.rotate(
angle: _arrowAnimation.value * 2.0 * math.pi,
child: child,
);
},
child: nowIcon),
focusColor: focusColor,
hoverColor: hoverColor,
highlightColor: highlightColor,
splashColor: splashColor,
disabledColor: disabledColor,
focusNode: focusNode,
autofocus: autofocus ?? false,
enableFeedback: enableFeedback ?? true,
autofocus: autofocus,
enableFeedback: enableFeedback,
tooltip: tooltip,
constraints: constraints,
visualDensity: visualDensity,
Expand Down
5 changes: 3 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
name: animated_icon_button
description: Flutter package to create custom animated IconButton. Includes all available icons. Based on native IconButton.
version: 0.3.0
version: 0.4.0
author: [email protected]
homepage: https://github.com/Frezyx/animated_icon_button

environment:
sdk: ">=2.7.0 <3.0.0"
sdk: ">=2.12.0-0 <3.0.0"
flutter: ">=1.22.0"

dependencies:
flutter:
Expand Down