In Flutter, what do FadeTransition, ScaleTransition, SlideTransition and SizeTransition each take, and how do their animated values translate on screen?
answer
- three doubles and one Offset
- opacity, scale factor, size factor
- SlideTransition offsets in child sizes
- only SizeTransition moves its neighbours
- alignment replaced axisAlignment
basics
~20 sFadeTransition takes an opacity, ScaleTransition a scale factor and SizeTransition a size factor, all Animation<double>. SlideTransition takes an Animation<Offset> measured in multiples of the child's own size. Only SizeTransition changes layout size, so only it moves neighbouring widgets.
solid answer
~40 s`FadeTransition(opacity:)` maps 0.0 to transparent and 1.0 to opaque, at the render-object level. `ScaleTransition(scale:)` applies a scale factor around `alignment` (default `Alignment.center`), and `RotationTransition(turns:)` rotates by value times a full turn. `SlideTransition(position:)` takes an `Animation<Offset>` in fractions of the child's own size - `Offset(1, 0)` is one child-width to the right - with `transformHitTests` on by default and `dx` flipped when `textDirection` is RTL. Those three are paint-time effects: the child keeps its layout slot, so siblings do not move. `SizeTransition(sizeFactor:)` clips its child and multiplies its own extent along `axis` (default `Axis.vertical`), so siblings reflow as it grows. In Flutter 3.47, position the revealed child with `alignment`; `axisAlignment` is deprecated.
code
dart · 24 linesimport 'package:flutter/material.dart';
// open is an Animation<double> from 0.0 (closed) to 1.0 (open),
// derived from an AnimationController owned by the surrounding State.
Widget buildFilters(Animation<double> open, Widget filters) {
return Column(
children: <Widget>[
const Text('Results'),
// Pushes the list below it down as it opens.
SizeTransition(
sizeFactor: open,
alignment: Alignment.topCenter,
child: filters,
),
// Slides in by its own height and fades, without moving anything.
SlideTransition(
position: open.drive(
Tween<Offset>(begin: const Offset(0, 1), end: Offset.zero),
),
child: FadeTransition(opacity: open, child: const Text('Filters applied')),
),
],
);
}go deeper
Recall each transition's parameter and type: opacity, scale, turns and sizeFactor are doubles, and SlideTransition's position is an Offset in child sizes.
Explain the split between paint-time transitions that leave layout alone and SizeTransition, which changes layout size and makes siblings reflow.
Pick the transition by its layout consequence, watch hit-testing on slid content, and migrate SizeTransition code from axisAlignment to alignment.
Standardise which transitions a design system exposes for entrances, reveals and loading states so their layout behaviour stays predictable across teams.
## Four transitions, two kinds of effect Flutter's `FooTransition` widgets each animate one visual property of a `child` from an explicit `Animation`. They split into two groups that interviewers like to probe: - **Paint-time effects** - `FadeTransition`, `ScaleTransition`, `RotationTransition`, `SlideTransition`. The child is laid out at its normal size and position; the effect is applied when painting. Neighbouring widgets **do not move**. - **Layout effects** - `SizeTransition`. It changes the size it reports to its parent, so neighbouring widgets in a `Column` or `Row` **reflow** as it animates. ## What each one takes | Widget | Parameter | Type | Meaning of the value | |---|---|---|---| | `FadeTransition` | `opacity` | `Animation<double>` | 0.0 transparent, 1.0 opaque | | `ScaleTransition` | `scale` | `Animation<double>` | scale factor about `alignment` (default `Alignment.center`) | | `RotationTransition` | `turns` | `Animation<double>` | 1.0 is one full turn, 0.5 a half turn | | `SlideTransition` | `position` | `Animation<Offset>` | offset in multiples of the **child's own** width and height | | `SizeTransition` | `sizeFactor` | `Animation<double>` | fraction of the child's extent along `axis` | ## FadeTransition `FadeTransition` is not an `AnimatedWidget`: it is a `SingleChildRenderObjectWidget` whose `RenderAnimatedOpacity` listens to the animation and updates its layer when the alpha changes, so a tick costs no widget build. Its `alwaysIncludeSemantics` flag (default `false`) decides whether a fully transparent child still appears in the semantics tree. Out-of-range opacity values are clamped when converted to alpha. ## ScaleTransition and RotationTransition Both extend `MatrixTransition`, which rebuilds a `Transform` from the animation value each tick. The scaled or rotated child still occupies its original layout box, so a scale above 1.0 draws over neighbours rather than pushing them away. Both accept an optional `filterQuality`, applied only while the animation is running. ## SlideTransition `SlideTransition` wraps its child in a `FractionalTranslation`. The key facts: 1. The offset is **relative to the child's size**, not in logical pixels: `Offset(0, 1)` moves the child down by its own height, which is why `Offset(0, 1)` to `Offset.zero` is the stock slide-up entrance. 2. `transformHitTests` defaults to `true`, so taps follow the translated child - but hit tests are still confined to the bounds of the `FractionalTranslation` itself, so content slid outside its original box cannot be tapped there. 3. If `textDirection` is `TextDirection.rtl`, the horizontal component is negated, so a slide authored as *from the start edge* mirrors correctly. ## SizeTransition `SizeTransition` builds a `ClipRect` around an `Align` whose `heightFactor` (for `Axis.vertical`, the default) or `widthFactor` (for `Axis.horizontal`) is the animation value, floored at zero. At 0.0 it takes no space along that axis; at 1.0 it takes the child's full extent. `fixedCrossAxisSizeFactor` optionally fixes the other axis. Where the revealed child sits inside the growing box is set by **`alignment`**; the older `axisAlignment` double is deprecated (see the version note), and passing both is an assertion error. ## Choosing in practice - A panel that should **push content down** as it opens: `SizeTransition`. - A toast that should **slide in over** content without moving it: `SlideTransition` plus `FadeTransition`. - A spinner or loading logo: `RotationTransition`. - A pop-in badge: `ScaleTransition`, perhaps with an overshooting curve on `scale`. ## Mistakes interviewers listen for - Treating `SlideTransition`'s offset as pixels and wondering why a narrow widget barely moves. - Expecting `ScaleTransition` to push neighbours aside. - Passing degrees or radians to `RotationTransition`'s `turns`. - Using `SizeTransition` for a pop-in and being surprised when the list below jumps. - Writing new code with `axisAlignment` after its deprecation.
- Why does a ScaleTransition at 1.2 overlap its neighbours instead of pushing them away?`ScaleTransition` applies a `Transform` at paint time. Layout has already given the child its normal box, and the scale only changes how that box is drawn, so neighbours stay where layout put them. To make surrounding content move, animate something that affects layout, such as `SizeTransition` or an explicitly animated size.
- What does SlideTransition's transformHitTests change?With the default `true`, hit testing applies the same translation as painting, so taps land on the child where it appears. With `false`, hit tests use the untranslated position, which suits purely decorative slides. Either way, hits are only detected inside the `FractionalTranslation`'s own bounds.
saying these in an interview costs you the question
- SlideTransition's Offset is measured in logical pixels.
- ScaleTransition makes neighbouring widgets move out of the way.
- RotationTransition's turns value is an angle in radians.
- SizeTransition scales the child's contents like ScaleTransition does.
- FadeTransition is just another AnimatedWidget that rebuilds each tick.