Skip to content

Commit

Permalink
Merge pull request #40 from splashbyte/version0.8.0
Browse files Browse the repository at this point in the history
version 0.8.0-beta.5
  • Loading branch information
maeddin committed Aug 18, 2023
2 parents 6c0c7ac + 138c944 commit 7b05d1a
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 39 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.8.0-beta.5 (2023-08-18)

- fixes `AnimationType.onHover`

## 0.8.0-beta.4 (2023-08-18)

- BREAKING: removes `IconTheme` for controlling default size of `Icon`s
Expand Down
8 changes: 8 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ class _MyHomePageState extends State<MyHomePage> {
),
AnimatedToggleSwitch<int>.rolling(
current: value,
indicatorIconScale: sqrt2,
values: const [0, 1, 2, 3],
onChanged: (i) {
setState(() => value = i);
Expand All @@ -350,10 +351,17 @@ class _MyHomePageState extends State<MyHomePage> {
),
AnimatedToggleSwitch<int?>.rolling(
allowUnlistedValues: true,
styleAnimationType: AnimationType.onHover,
current: nullableValue,
values: const [0, 1, 2, 3],
onChanged: (i) => setState(() => nullableValue = i),
iconBuilder: rollingIconBuilder,
customStyleBuilder: (context, local, global) {
final color = local.isValueListed
? null
: Theme.of(context).colorScheme.error;
return ToggleStyle(borderColor: color, indicatorColor: color);
},
),
Padding(
padding: const EdgeInsets.all(8.0),
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.8.0-beta.3"
version: "0.8.0-beta.5"
async:
dependency: transitive
description:
Expand Down
2 changes: 2 additions & 0 deletions lib/animated_toggle_switch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

part 'src/animation_type_builder.dart';
part 'src/properties.dart';
part 'src/style.dart';
part 'src/tweens.dart';
part 'src/cursors.dart';
part 'src/foreground_indicator_transition.dart';
part 'src/widgets/animated_toggle_switch.dart';
Expand Down
93 changes: 93 additions & 0 deletions lib/src/animation_type_builder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
part of 'package:animated_toggle_switch/animated_toggle_switch.dart';

class _AnimationTypeHoverBuilder<T, V> extends StatefulWidget {
final V Function(StyledToggleProperties<T> local) valueProvider;
final V Function(V value1, V value2, double t) lerp;
final Widget Function(V value) builder;
final GlobalToggleProperties<T> properties;
final Duration animationDuration;
final Curve animationCurve;
final Duration indicatorAppearingDuration;
final Curve indicatorAppearingCurve;

const _AnimationTypeHoverBuilder({
required this.valueProvider,
required this.lerp,
required this.builder,
required this.properties,
required this.animationDuration,
required this.animationCurve,
required this.indicatorAppearingDuration,
required this.indicatorAppearingCurve,
});

@override
State<_AnimationTypeHoverBuilder<T, V>> createState() =>
_AnimationTypeHoverBuilderState();
}

class _AnimationTypeHoverBuilderState<T, V>
extends State<_AnimationTypeHoverBuilder<T, V>> {
final _builderKey = GlobalKey();
T? _lastUnlistedValue;

@override
void initState() {
super.initState();
if (!widget.properties.isCurrentListed) {
_lastUnlistedValue = widget.properties.current;
}
}

@override
void didUpdateWidget(covariant _AnimationTypeHoverBuilder<T, V> oldWidget) {
super.didUpdateWidget(oldWidget);
if (!widget.properties.isCurrentListed) {
_lastUnlistedValue = widget.properties.current;
}
}

@override
Widget build(BuildContext context) {
final pos = widget.properties.position;
final values = widget.properties.values;
final index1 = pos.floor();
final index2 = pos.ceil();
final isListed = widget.properties.isCurrentListed;
V listedValueFunction() => widget.lerp(
widget.valueProvider(
StyledToggleProperties(value: values[index1], index: index1)),
widget.valueProvider(
StyledToggleProperties(value: values[index2], index: index2)),
pos - pos.floor(),
);
final unlistedDoubleValue = isListed ? 0.0 : 1.0;
return TweenAnimationBuilder<double>(
duration: widget.indicatorAppearingDuration,
curve: widget.indicatorAppearingCurve,
tween: Tween(begin: unlistedDoubleValue, end: unlistedDoubleValue),
builder: (context, unlistedDoubleValue, _) {
if (unlistedDoubleValue == 0.0) {
return _EmptyWidget(
key: _builderKey, child: widget.builder(listedValueFunction()));
}
final unlistedValue = widget.valueProvider(
StyledToggleProperties(value: _lastUnlistedValue as T, index: -1));
return TweenAnimationBuilder<V>(
duration: widget.animationDuration,
curve: widget.animationCurve,
tween: _CustomTween(widget.lerp,
begin: unlistedValue, end: unlistedValue),
builder: (context, unlistedValue, _) {
return _EmptyWidget(
key: _builderKey,
child: widget.builder(unlistedDoubleValue == 1.0
? unlistedValue
: widget.lerp(listedValueFunction(), unlistedValue,
unlistedDoubleValue)),
);
});
},
);
}
}
8 changes: 7 additions & 1 deletion lib/src/properties.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class GlobalToggleProperties<T> {
/// If [values] does not contain [current], this value is set to [-1].
final int currentIndex;

/// This value indicates if [values] does contain [current].
bool get isCurrentListed => currentIndex >= 0;

/// The previous value of the switch.
final T? previous;

Expand Down Expand Up @@ -94,9 +97,12 @@ class LocalToggleProperties<T> {

/// The index of [value].
///
/// This value is [-1] if [values] does not contain [value].
/// If [values] does not contain [value], this value is set to [-1].
final int index;

/// This value indicates if [values] does contain [value].
bool get isValueListed => index >= 0;

const LocalToggleProperties({
required this.value,
required this.index,
Expand Down
10 changes: 10 additions & 0 deletions lib/src/tweens.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
part of 'package:animated_toggle_switch/animated_toggle_switch.dart';

class _CustomTween<V> extends Tween<V> {
final V Function(V value1, V value2, double t) lerpFunction;

_CustomTween(this.lerpFunction, {super.begin, super.end});

@override
V lerp(double t) => lerpFunction(begin as V, end as V, t);
}
49 changes: 13 additions & 36 deletions lib/src/widgets/animated_toggle_switch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1064,14 +1064,10 @@ class AnimatedToggleSwitch<T> extends _AnimatedToggleSwitchParent<T> {
padding: EdgeInsets.all(borderWidth),
active: active,
wrapperBuilder: (context, global, child) {
return _ConditionalWrapper(
condition: inactiveOpacity < 1.0,
wrapper: (context, child) => AnimatedOpacity(
opacity: global.active ? 1.0 : inactiveOpacity,
duration: inactiveOpacityDuration,
curve: inactiveOpacityCurve,
child: child,
),
return AnimatedOpacity(
opacity: global.active ? 1.0 : inactiveOpacity,
duration: inactiveOpacityDuration,
curve: inactiveOpacityCurve,
child: _animationTypeBuilder<ToggleStyle>(
context,
styleAnimationType,
Expand Down Expand Up @@ -1110,7 +1106,6 @@ class AnimatedToggleSwitch<T> extends _AnimatedToggleSwitchParent<T> {
});
}

//TODO: extract this method to separate widget
Widget _animationTypeBuilder<V>(
BuildContext context,
AnimationType animationType,
Expand All @@ -1119,7 +1114,6 @@ class AnimatedToggleSwitch<T> extends _AnimatedToggleSwitchParent<T> {
Widget Function(V value) builder,
GlobalToggleProperties<T> properties,
) {
double pos = properties.position;
switch (animationType) {
case AnimationType.onSelected:
V currentValue = valueProvider(
Expand All @@ -1133,23 +1127,15 @@ class AnimatedToggleSwitch<T> extends _AnimatedToggleSwitchParent<T> {
builder: (context, value, _) => builder(value),
);
case AnimationType.onHover:
final index1 = pos.floor();
final index2 = pos.ceil();
final currentValue = properties.currentIndex < 0
? valueProvider(
StyledToggleProperties(value: properties.current, index: -1))
: lerp(
valueProvider(StyledToggleProperties(
value: values[index1], index: index1)),
valueProvider(StyledToggleProperties(
value: values[index2], index: index2)),
pos - pos.floor(),
);
return TweenAnimationBuilder<V>(
duration: animationDuration,
curve: animationCurve,
tween: _CustomTween(lerp, begin: currentValue, end: currentValue),
builder: (context, value, _) => builder(value),
return _AnimationTypeHoverBuilder(
valueProvider: valueProvider,
lerp: lerp,
builder: builder,
properties: properties,
animationDuration: animationDuration,
animationCurve: animationCurve,
indicatorAppearingDuration: indicatorAppearingDuration,
indicatorAppearingCurve: indicatorAppearingCurve,
);
}
}
Expand Down Expand Up @@ -1318,15 +1304,6 @@ class _MyLoading extends StatelessWidget {
}
}

class _CustomTween<V> extends Tween<V> {
final V Function(V value1, V value2, double t) lerpFunction;

_CustomTween(this.lerpFunction, {super.begin, super.end});

@override
V lerp(double t) => lerpFunction(begin as V, end as V, t);
}

extension _XTargetPlatform on TargetPlatform {
bool get isApple =>
this == TargetPlatform.iOS || this == TargetPlatform.macOS;
Expand Down
3 changes: 3 additions & 0 deletions lib/src/widgets/conditional_wrapper.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
part of 'package:animated_toggle_switch/animated_toggle_switch.dart';

// this widget is not covered because it is not used currently
// coverage:ignore-start
class _ConditionalWrapper extends StatefulWidget {
final Widget Function(BuildContext context, Widget child) wrapper;
final bool condition;
Expand All @@ -25,6 +27,7 @@ class _ConditionalWrapperState extends State<_ConditionalWrapper> {
return child;
}
}
// coverage:ignore-end

class _EmptyWidget extends StatelessWidget {
final Widget child;
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: animated_toggle_switch
description: Fully customizable, draggable and animated switch with multiple choices and smooth loading animation. It has prebuilt constructors for rolling and size animations.
version: 0.8.0-beta.4
version: 0.8.0-beta.5
repository: https://github.com/SplashByte/animated_toggle_switch
issue_tracker: https://github.com/SplashByte/animated_toggle_switch/issues

Expand Down

0 comments on commit 7b05d1a

Please sign in to comment.