|
|
@ -1,4 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'dart:math' as math;
|
|
|
|
import 'dart:math' as math;
|
|
|
|
|
|
|
|
|
|
|
@ -25,18 +24,18 @@ class IconToggle extends StatefulWidget {
|
|
|
|
final Color activeColor;
|
|
|
|
final Color activeColor;
|
|
|
|
final Color inactiveColor;
|
|
|
|
final Color inactiveColor;
|
|
|
|
final bool value;
|
|
|
|
final bool value;
|
|
|
|
final ValueChanged<bool> onChanged;
|
|
|
|
final ValueChanged<bool>? onChanged;
|
|
|
|
final AnimatedSwitcherTransitionBuilder transitionBuilder;
|
|
|
|
final AnimatedSwitcherTransitionBuilder transitionBuilder;
|
|
|
|
final Duration duration;
|
|
|
|
final Duration duration;
|
|
|
|
final Duration reverseDuration;
|
|
|
|
final Duration? reverseDuration;
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
_IconToggleState createState() => _IconToggleState();
|
|
|
|
_IconToggleState createState() => _IconToggleState();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class _IconToggleState extends State<IconToggle>
|
|
|
|
class _IconToggleState extends State<IconToggle>
|
|
|
|
with SingleTickerProviderStateMixin {
|
|
|
|
with SingleTickerProviderStateMixin {
|
|
|
|
AnimationController _controller;
|
|
|
|
AnimationController? _controller;
|
|
|
|
Animation<double> _position;
|
|
|
|
late Animation<double> _position;
|
|
|
|
bool _cancel = false;
|
|
|
|
bool _cancel = false;
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
@ -46,12 +45,12 @@ class _IconToggleState extends State<IconToggle>
|
|
|
|
vsync: this,
|
|
|
|
vsync: this,
|
|
|
|
duration: Duration(milliseconds: 100),
|
|
|
|
duration: Duration(milliseconds: 100),
|
|
|
|
reverseDuration: Duration(milliseconds: 50));
|
|
|
|
reverseDuration: Duration(milliseconds: 50));
|
|
|
|
_position = CurvedAnimation(parent: _controller, curve: Curves.linear);
|
|
|
|
_position = CurvedAnimation(parent: _controller!, curve: Curves.linear);
|
|
|
|
_position.addStatusListener((status) {
|
|
|
|
_position.addStatusListener((status) {
|
|
|
|
if (status == AnimationStatus.dismissed &&
|
|
|
|
if (status == AnimationStatus.dismissed &&
|
|
|
|
widget.onChanged != null &&
|
|
|
|
widget.onChanged != null &&
|
|
|
|
_cancel == false) {
|
|
|
|
_cancel == false) {
|
|
|
|
widget.onChanged(!widget.value);
|
|
|
|
widget.onChanged!(!widget.value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -88,7 +87,9 @@ class _IconToggleState extends State<IconToggle>
|
|
|
|
reverseDuration: widget.reverseDuration,
|
|
|
|
reverseDuration: widget.reverseDuration,
|
|
|
|
transitionBuilder: widget.transitionBuilder,
|
|
|
|
transitionBuilder: widget.transitionBuilder,
|
|
|
|
child: Icon(
|
|
|
|
child: Icon(
|
|
|
|
widget.value ? widget.selectedIconData : widget.unselectedIconData,
|
|
|
|
widget.value
|
|
|
|
|
|
|
|
? widget.selectedIconData
|
|
|
|
|
|
|
|
: widget.unselectedIconData,
|
|
|
|
color: widget.value ? widget.activeColor : widget.inactiveColor,
|
|
|
|
color: widget.value ? widget.activeColor : widget.inactiveColor,
|
|
|
|
size: 22,
|
|
|
|
size: 22,
|
|
|
|
key: ValueKey<bool>(widget.value),
|
|
|
|
key: ValueKey<bool>(widget.value),
|
|
|
@ -102,19 +103,19 @@ class _IconToggleState extends State<IconToggle>
|
|
|
|
|
|
|
|
|
|
|
|
class _IconToggleable<T> extends AnimatedWidget {
|
|
|
|
class _IconToggleable<T> extends AnimatedWidget {
|
|
|
|
_IconToggleable({
|
|
|
|
_IconToggleable({
|
|
|
|
Animation<T> listenable,
|
|
|
|
required Animation<T> listenable,
|
|
|
|
this.activeColor,
|
|
|
|
this.activeColor,
|
|
|
|
this.inactiveColor,
|
|
|
|
this.inactiveColor,
|
|
|
|
this.child,
|
|
|
|
this.child,
|
|
|
|
}) : super(listenable: listenable);
|
|
|
|
}) : super(listenable: listenable);
|
|
|
|
final Color activeColor;
|
|
|
|
final Color? activeColor;
|
|
|
|
final Color inactiveColor;
|
|
|
|
final Color? inactiveColor;
|
|
|
|
final Widget child;
|
|
|
|
final Widget? child;
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return CustomPaint(
|
|
|
|
return CustomPaint(
|
|
|
|
painter: _IconPainter(
|
|
|
|
painter: _IconPainter(
|
|
|
|
position: listenable,
|
|
|
|
position: listenable as Animation<double>,
|
|
|
|
activeColor: activeColor,
|
|
|
|
activeColor: activeColor,
|
|
|
|
inactiveColor: inactiveColor,
|
|
|
|
inactiveColor: inactiveColor,
|
|
|
|
),
|
|
|
|
),
|
|
|
@ -125,20 +126,20 @@ class _IconToggleable<T> extends AnimatedWidget {
|
|
|
|
|
|
|
|
|
|
|
|
class _IconPainter extends CustomPainter {
|
|
|
|
class _IconPainter extends CustomPainter {
|
|
|
|
_IconPainter({
|
|
|
|
_IconPainter({
|
|
|
|
@required this.position,
|
|
|
|
required this.position,
|
|
|
|
this.activeColor,
|
|
|
|
this.activeColor,
|
|
|
|
this.inactiveColor,
|
|
|
|
this.inactiveColor,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
final Animation<double> position;
|
|
|
|
final Animation<double> position;
|
|
|
|
final Color activeColor;
|
|
|
|
final Color? activeColor;
|
|
|
|
final Color inactiveColor;
|
|
|
|
final Color? inactiveColor;
|
|
|
|
|
|
|
|
|
|
|
|
double get _value => position != null ? position.value : 0;
|
|
|
|
double get _value => position.value;
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
void paint(Canvas canvas, Size size) {
|
|
|
|
void paint(Canvas canvas, Size size) {
|
|
|
|
final Paint paint = Paint()
|
|
|
|
final Paint paint = Paint()
|
|
|
|
..color = Color.lerp(inactiveColor, activeColor, _value)
|
|
|
|
..color = Color.lerp(inactiveColor, activeColor, _value)!
|
|
|
|
.withOpacity(math.min(_value, 0.15))
|
|
|
|
.withOpacity(math.min(_value, 0.15))
|
|
|
|
..style = PaintingStyle.fill
|
|
|
|
..style = PaintingStyle.fill
|
|
|
|
..strokeWidth = 2.0;
|
|
|
|
..strokeWidth = 2.0;
|
|
|
|