stack_wallet/lib/widgets/expandable.dart

137 lines
3.6 KiB
Dart
Raw Normal View History

2023-05-26 21:21:16 +00:00
/*
* This file is part of Stack Wallet.
*
* Copyright (c) 2023 Cypher Stack
* All Rights Reserved.
* The code is distributed under GPLv3 license, see LICENSE file for details.
* Generated by Cypher Stack on 2023-05-26
*
*/
2022-09-19 17:34:43 +00:00
import 'package:flutter/material.dart';
enum ExpandableState {
collapsed,
2022-11-17 16:12:19 +00:00
expanded,
2022-09-19 17:34:43 +00:00
}
2022-10-31 17:51:16 +00:00
class ExpandableController {
VoidCallback? toggle;
ExpandableState state = ExpandableState.collapsed;
}
2022-09-19 17:34:43 +00:00
class Expandable extends StatefulWidget {
const Expandable({
Key? key,
required this.header,
required this.body,
this.animationController,
this.animation,
this.animationDurationMultiplier = 1.0,
this.onExpandChanged,
2023-02-27 23:51:22 +00:00
this.onExpandWillChange,
2022-10-31 17:51:16 +00:00
this.controller,
this.expandOverride,
this.curve = Curves.easeInOut,
2023-04-07 23:21:11 +00:00
this.initialState = ExpandableState.collapsed,
2022-09-19 17:34:43 +00:00
}) : super(key: key);
final Widget header;
final Widget body;
final AnimationController? animationController;
final Animation<double>? animation;
final double animationDurationMultiplier;
final void Function(ExpandableState)? onExpandChanged;
2023-02-27 23:51:22 +00:00
final void Function(ExpandableState)? onExpandWillChange;
2022-10-31 17:51:16 +00:00
final ExpandableController? controller;
final VoidCallback? expandOverride;
final Curve curve;
2023-04-07 23:21:11 +00:00
final ExpandableState initialState;
2022-09-19 17:34:43 +00:00
@override
State<Expandable> createState() => _ExpandableState();
}
class _ExpandableState extends State<Expandable> with TickerProviderStateMixin {
late final AnimationController animationController;
late final Animation<double> animation;
late final Duration duration;
2022-10-31 17:51:16 +00:00
late final ExpandableController? controller;
2023-04-07 23:21:11 +00:00
late ExpandableState _toggleState;
2022-09-19 17:34:43 +00:00
Future<void> toggle() async {
if (animation.isDismissed) {
2023-02-27 23:51:22 +00:00
widget.onExpandWillChange?.call(ExpandableState.expanded);
2022-09-19 17:34:43 +00:00
await animationController.forward();
2022-11-17 16:12:19 +00:00
_toggleState = ExpandableState.expanded;
2022-10-31 17:51:16 +00:00
widget.onExpandChanged?.call(_toggleState);
2022-09-19 17:34:43 +00:00
} else if (animation.isCompleted) {
2023-02-27 23:51:22 +00:00
widget.onExpandWillChange?.call(ExpandableState.collapsed);
2022-09-19 17:34:43 +00:00
await animationController.reverse();
2022-11-17 16:12:19 +00:00
_toggleState = ExpandableState.collapsed;
2022-10-31 17:51:16 +00:00
widget.onExpandChanged?.call(_toggleState);
2022-09-19 17:34:43 +00:00
}
2022-10-31 17:51:16 +00:00
controller?.state = _toggleState;
2022-09-19 17:34:43 +00:00
}
@override
void initState() {
2023-04-07 23:21:11 +00:00
_toggleState = widget.initialState;
2022-10-31 17:51:16 +00:00
controller = widget.controller;
controller?.toggle = toggle;
2022-09-19 17:34:43 +00:00
duration = Duration(
milliseconds: (500 * widget.animationDurationMultiplier).toInt(),
);
animationController = widget.animationController ??
AnimationController(
vsync: this,
duration: duration,
);
2023-04-07 23:21:11 +00:00
final tween = _toggleState == ExpandableState.collapsed
? Tween<double>(begin: 0.0, end: 1.0)
: Tween<double>(begin: 1.0, end: 0.0);
2022-09-19 17:34:43 +00:00
animation = widget.animation ??
2023-04-07 23:21:11 +00:00
tween.animate(
2022-09-19 17:34:43 +00:00
CurvedAnimation(
curve: widget.curve,
2022-09-19 17:34:43 +00:00
parent: animationController,
),
);
super.initState();
}
@override
void dispose() {
animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: widget.expandOverride ?? toggle,
child: Container(
color: Colors.transparent,
child: widget.header,
),
2022-09-19 17:34:43 +00:00
),
),
SizeTransition(
sizeFactor: animation,
axisAlignment: 1.0,
child: widget.body,
),
],
);
}
}