PositionedTransition is a Flutter widget that creates an animated transition between two positions within a Stack
widget. It’s used to move a child widget from one position to another with an animation.
Key Features:
- Animated Transition: PositionedTransition creates a smooth animation between the initial and final positions.
- Stack Integration: It’s designed to work within a Stack widget, allowing for layered layouts.
- Customizable Animation: You can control the animation duration and curve.
Properties:
child
: The widget to be transitioned.rect
:An Animation<
RelativeRect>
that defines the transition between positions.duration
: The length of time the animation takes to complete (default is 200 milliseconds).curve
: The animation curve (default is Curves.linear).
How to Use PositionedTransition:
- Wrap the
PositionedTransition
widget inside aStack
. - Define the
child
widget to be transitioned. - Set the initial and final positions using the
rect
property. - Control the animation using
duration
andcurve
. - Use
setState
to trigger the animation.
Example
import 'package:flutter/material.dart';
// This StatefulWidget uses PositionedTransition to animate the position of a widget.
class PositionedTransitionScreen extends StatefulWidget {
// Constructor for the PositionedTransitionScreen, accepting an optional key.
const PositionedTransitionScreen({Key? key, required BoxDecoration decoration}) : super(key: key);
@override
_PositionedTransitionScreenState createState() => _PositionedTransitionScreenState();
}
class _PositionedTransitionScreenState extends State<PositionedTransitionScreen> with SingleTickerProviderStateMixin {
// AnimationController controls the animation's duration and progress.
late AnimationController _controller;
// Animation<RelativeRect> controls the position of the child widget.
late Animation<RelativeRect> _animation;
@override
void initState() {
super.initState();
// Initialize the AnimationController with a duration of 2 seconds.
// The 'vsync' prevents off-screen animations from consuming unnecessary resources.
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)
// Start the animation in a repeating loop that reverses when it finishes.
..repeat(reverse: true);
// Create an animation that transitions between two different positions (begin and end).
// The positions are defined using RelativeRect.fromLTRB, which specifies the
// left, top, right, and bottom offsets of the widget relative to its parent.
_animation = RelativeRectTween(
begin: RelativeRect.fromLTRB(0, 0, 200, 200), // Starting position of the widget
end: RelativeRect.fromLTRB(200, 200, 0, 0), // Ending position of the widget
).animate(_controller); // Bind this animation to the controller.
}
@override
void dispose() {
// Dispose of the AnimationController when the widget is destroyed to free up resources.
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
// The AppBar contains a gradient background and a title.
appBar: AppBar(
title: Text("PositionedTransition Example"),
// FlexibleSpace allows for customizing the AppBar background.
flexibleSpace: Container(
// The gradient goes from deep purple on the top left to orange on the top right.
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.deepPurple, Colors.orangeAccent],
begin: Alignment.topLeft,
end: Alignment.topRight,
),
),
),
),
// The body of the Scaffold contains a Stack widget.
// Stack allows for layering of widgets on top of each other.
body: Stack(
children: [
// PositionedTransition animates the position of its child using the provided animation.
PositionedTransition(
// The rect parameter takes the animation created earlier,
// which controls the position of the widget.
rect: _animation,
// This child widget is a blue container with a size of 100x100.
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
),
],
),
);
}
}