@@ -8,10 +8,6 @@ typedef RollBuilder = Widget Function(
88 Widget child,
99);
1010
11- Widget _defaultRollInBuilder (BuildContext context, Widget child) => child;
12-
13- Widget _defaultRollOutBuilder (BuildContext context, Widget child) => child;
14-
1511/// Provides a extension method to apply an [RollEffect] to a [Widget] .
1612extension RollEffectExtension on Widget ? {
1713 /// Applies an [RollEffect] to a [Widget] with the given [slideInDirection] ,
@@ -20,10 +16,7 @@ extension RollEffectExtension on Widget? {
2016 AxisDirection slideInDirection = AxisDirection .up,
2117 AxisDirection slideOutDirection = AxisDirection .up,
2218 double multiplier = 1 ,
23- bool useSnapshots = true ,
24- bool rollInitially = false ,
25- RollBuilder ? rollInBuilder,
26- RollBuilder ? rollOutBuilder,
19+ bool useSnapshots = false ,
2720 }) =>
2821 EffectWidget (
2922 end: RollEffect (
@@ -32,9 +25,6 @@ extension RollEffectExtension on Widget? {
3225 slideOutDirection: slideOutDirection,
3326 multiplier: multiplier,
3427 useSnapshots: useSnapshots,
35- rollInitially: rollInitially,
36- rollInBuilder: rollInBuilder ?? _defaultRollInBuilder,
37- rollOutBuilder: rollOutBuilder ?? _defaultRollOutBuilder,
3828 ),
3929 child: this ,
4030 );
@@ -63,28 +53,13 @@ class RollEffect extends Effect {
6353 /// may be sensitive.
6454 final bool useSnapshots;
6555
66- /// Determines whether this effect starts from no widget and immediately rolls
67- /// in the passed [child] immediately once triggered, or if this roll effect
68- /// should only trigger if the [child] passed has changed from its initial
69- /// or last state.
70- final bool rollInitially;
71-
72- /// The builder to use when rolling in the [Widget] .
73- final RollBuilder rollInBuilder;
74-
75- /// The builder to use when rolling out the [Widget] .
76- final RollBuilder rollOutBuilder;
77-
7856 /// Creates a [RollEffect] with the given parameters.
7957 const RollEffect ({
8058 required this .child,
8159 this .slideInDirection = AxisDirection .up,
8260 this .slideOutDirection = AxisDirection .up,
8361 this .multiplier = 1 ,
84- this .useSnapshots = true ,
85- this .rollInitially = false ,
86- this .rollInBuilder = _defaultRollInBuilder,
87- this .rollOutBuilder = _defaultRollOutBuilder,
62+ this .useSnapshots = false ,
8863 });
8964
9065 @override
@@ -96,9 +71,6 @@ class RollEffect extends Effect {
9671 slideOutDirection: slideOutDirection,
9772 multiplier: multiplier,
9873 useSnapshots: useSnapshots,
99- rollInitially: rollInitially,
100- rollInBuilder: rollInBuilder,
101- rollOutBuilder: rollOutBuilder,
10274 child: child,
10375 );
10476
@@ -109,9 +81,6 @@ class RollEffect extends Effect {
10981 slideOutDirection,
11082 multiplier,
11183 useSnapshots,
112- rollInitially,
113- rollInBuilder,
114- rollOutBuilder,
11584 ];
11685}
11786
@@ -137,18 +106,6 @@ class RollingEffectWidget extends StatefulWidget {
137106 /// may be sensitive.
138107 final bool useSnapshots;
139108
140- /// Determines whether this effect starts from no widget and immediately rolls
141- /// in the passed [child] once triggered, or if this roll effect
142- /// should only trigger if the [child] passed has changed from its initial
143- /// or last state.
144- final bool rollInitially;
145-
146- /// The builder to use when rolling in the [Widget] .
147- final RollBuilder rollInBuilder;
148-
149- /// The builder to use when rolling out the [Widget] .
150- final RollBuilder rollOutBuilder;
151-
152109 /// Creates a [RollingEffectWidget] with the given parameters.
153110 const RollingEffectWidget ({
154111 super .key,
@@ -157,9 +114,6 @@ class RollingEffectWidget extends StatefulWidget {
157114 this .slideOutDirection = AxisDirection .up,
158115 this .multiplier = 1 ,
159116 this .useSnapshots = false ,
160- this .rollInitially = false ,
161- this .rollInBuilder = _defaultRollInBuilder,
162- this .rollOutBuilder = _defaultRollOutBuilder,
163117 });
164118
165119 @override
@@ -173,16 +127,14 @@ class _RollingEffectWidgetState extends State<RollingEffectWidget> {
173127 int retainedWidgets = 0 ;
174128 Widget ? oldChild;
175129
176- late bool isInitialRoll = widget.rollInitially;
177-
178- bool get canRoll => isInitialRoll || oldChild != null ;
130+ bool canRoll = false ;
179131
180132 @override
181133 void didUpdateWidget (covariant RollingEffectWidget oldWidget) {
182134 super .didUpdateWidget (oldWidget);
183135
184136 if (oldWidget.child? .key != widget.child? .key) {
185- isInitialRoll = false ;
137+ canRoll = true ;
186138 if (widget.useSnapshots) {
187139 oldChild = SnapshotWidget (
188140 key: ValueKey (retainedWidgets++ ),
@@ -228,26 +180,18 @@ class _RollingEffectWidgetState extends State<RollingEffectWidget> {
228180 AxisDirection .left || AxisDirection .right => Offset (slideOutTime, 0 ),
229181 };
230182
231- final child = widget.child == null
183+ final Widget ? child = widget.child;
184+
185+ late final Widget ? oldRoll = oldChild == null
232186 ? null
233- : widget.rollInBuilder (
234- context,
235- widget.child! ,
187+ : FractionalTranslation (
188+ transformHitTests: false ,
189+ translation: slideOutOffset * widget.multiplier,
190+ child: oldChild,
236191 );
237192
238- final oldRoll = FractionalTranslation (
239- transformHitTests: false ,
240- translation: slideOutOffset * widget.multiplier,
241- child: oldChild == null
242- ? null
243- : widget.rollOutBuilder (
244- context,
245- oldChild! ,
246- ),
247- );
248-
249- late final double clampedTime = timeValue.clamp (0 , 1 );
250- late final double reverseClampedTime = 1 - clampedTime;
193+ final double clampedTime = timeValue.clamp (0 , 1 );
194+ final double reverseClampedTime = 1 - clampedTime;
251195
252196 return AnimatedSize (
253197 duration: query? .duration ?? Duration .zero,
@@ -257,23 +201,35 @@ class _RollingEffectWidgetState extends State<RollingEffectWidget> {
257201 clipBehavior: Clip .none,
258202 alignment: Alignment .center,
259203 children: [
260- if (oldChild != null )
261- child == null
262- ? Align (
263- heightFactor: reverseClampedTime,
264- widthFactor: reverseClampedTime,
204+ if (oldRoll != null )
205+ // If the main child is null, then we can't use a Positioned.fill
206+ // widget to fill the entire space with the old roll because a stack
207+ // must have at least one non-positioned child. Use an Align widget
208+ // instead. The stack's size will be determined by the size of the
209+ // old rolling widget.
210+ if (child == null )
211+ Align (
212+ heightFactor: reverseClampedTime,
213+ widthFactor: reverseClampedTime,
214+ child: oldRoll,
215+ )
216+ else
217+ // If the main child is not null, then we can use a
218+ // Positioned.fill widget to fill the entire space with the old
219+ // roll. The stack's size will be determined by the size of the
220+ // main child, while this old roll is de-transitioned.
221+ // The FittedBox ensures that the oldRoll is laid out as if it
222+ // were the main child, unaffected by the main child's size.
223+ Positioned .fill (
224+ child: Align (
225+ heightFactor: reverseClampedTime,
226+ widthFactor: reverseClampedTime,
227+ child: FittedBox (
228+ fit: BoxFit .none,
265229 child: oldRoll,
266- )
267- : Positioned .fill (
268- child: Align (
269- heightFactor: reverseClampedTime,
270- widthFactor: reverseClampedTime,
271- child: FittedBox (
272- fit: BoxFit .none,
273- child: oldRoll,
274- ),
275- ),
276230 ),
231+ ),
232+ ),
277233 if (child != null )
278234 FractionalTranslation (
279235 transformHitTests: false ,
0 commit comments