1
1
import 'package:flutter/material.dart' ;
2
2
3
- class Closeable extends StatelessWidget {
4
- static const _defaultDuration = Duration (milliseconds: 250 );
3
+ const _defaultDuration = Duration (milliseconds: 250 );
5
4
5
+ /// [Closeable] provides a widget that will animate to closed or open positions depending
6
+ /// on the `open` or `closed` parameter values. One and only one of `open` or `closed` must
7
+ /// be provided.
8
+ class Closeable extends StatelessWidget {
6
9
final Duration duration;
7
10
final double _value;
8
11
final Widget child;
12
+ final Axis orientation;
9
13
10
14
const Closeable ({
11
15
super .key,
12
16
bool ? closed,
13
17
bool ? open,
14
18
required this .child,
15
19
this .duration = _defaultDuration,
20
+ this .orientation = Axis .vertical,
16
21
}) : assert ((closed is bool ) || (open is bool ), 'One of closed or open required' ),
17
22
assert ((closed is bool ) != (open is bool ), 'Only one of closed or open allowed' ),
18
23
_value = (open == true || closed == false ) ? 1 : 0 ;
@@ -25,10 +30,61 @@ class Closeable extends StatelessWidget {
25
30
child: AnimatedAlign (
26
31
duration: duration,
27
32
alignment: Alignment .topLeft,
28
- heightFactor: _value,
33
+ heightFactor: orientation == Axis .vertical ? _value : null ,
34
+ widthFactor: orientation == Axis .horizontal ? _value : null ,
29
35
child: child,
30
36
),
31
37
),
32
38
);
33
39
}
34
40
}
41
+
42
+ /// [AnimatingCloseable] provides a closeable widget just like [Closeable]
43
+ /// with the minor difference that it animates to its first position from closed
44
+ class AnimatingCloseable extends StatefulWidget {
45
+ final Duration duration;
46
+ final bool ? open;
47
+ final bool ? closed;
48
+ final Widget child;
49
+ final Axis orientation;
50
+
51
+ const AnimatingCloseable ({
52
+ super .key,
53
+ this .open,
54
+ this .closed,
55
+ required this .child,
56
+ this .duration = _defaultDuration,
57
+ this .orientation = Axis .vertical,
58
+ }) : assert ((closed is bool ) || (open is bool ), 'One of closed or open required' ),
59
+ assert ((closed is bool ) != (open is bool ), 'Only one of closed or open allowed' );
60
+
61
+ @override
62
+ State <AnimatingCloseable > createState () => _AnimatingCloseableState ();
63
+ }
64
+
65
+ class _AnimatingCloseableState extends State <AnimatingCloseable > {
66
+ bool ? open = false ;
67
+ bool ? closed;
68
+
69
+ @override
70
+ void initState () {
71
+ super .initState ();
72
+ WidgetsBinding .instance.addPostFrameCallback ((_) {
73
+ setState (() {
74
+ open = widget.open;
75
+ closed = widget.closed;
76
+ });
77
+ });
78
+ }
79
+
80
+ @override
81
+ Widget build (BuildContext context) {
82
+ return Closeable (
83
+ duration: widget.duration,
84
+ open: open,
85
+ closed: closed,
86
+ orientation: widget.orientation,
87
+ child: widget.child,
88
+ );
89
+ }
90
+ }
0 commit comments