1
0
mirror of https://github.com/flutter/samples.git synced 2025-11-08 13:58:47 +00:00

Flutter 3.29 beta (#2571)

This commit is contained in:
Eric Windmill
2025-02-12 18:08:01 -05:00
committed by GitHub
parent d62c784789
commit 719fd72c38
685 changed files with 76244 additions and 53721 deletions

View File

@@ -27,11 +27,13 @@ void setupWindow() {
setWindowMinSize(const Size(windowWidth, windowHeight));
setWindowMaxSize(const Size(windowWidth, windowHeight));
getCurrentScreen().then((screen) {
setWindowFrame(Rect.fromCenter(
center: screen!.frame.center,
width: windowWidth,
height: windowHeight,
));
setWindowFrame(
Rect.fromCenter(
center: screen!.frame.center,
width: windowWidth,
height: windowHeight,
),
);
});
}
}
@@ -41,11 +43,7 @@ class Demo {
final String route;
final WidgetBuilder builder;
const Demo({
required this.name,
required this.route,
required this.builder,
});
const Demo({required this.name, required this.route, required this.builder});
}
final basicDemos = [
@@ -182,9 +180,7 @@ class AnimationSamples extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Animation Samples',
theme: ThemeData(
colorSchemeSeed: Colors.deepPurple,
),
theme: ThemeData(colorSchemeSeed: Colors.deepPurple),
routerConfig: router,
);
}
@@ -197,9 +193,7 @@ class HomePage extends StatelessWidget {
Widget build(BuildContext context) {
final headerStyle = Theme.of(context).textTheme.titleLarge;
return Scaffold(
appBar: AppBar(
title: const Text('Animation Samples'),
),
appBar: AppBar(title: const Text('Animation Samples')),
body: ListView(
children: [
ListTile(title: Text('Basics', style: headerStyle)),

View File

@@ -24,8 +24,10 @@ class _AnimatedBuilderDemoState extends State<AnimatedBuilderDemo>
void initState() {
super.initState();
controller = AnimationController(vsync: this, duration: duration);
animation =
ColorTween(begin: beginColor, end: endColor).animate(controller);
animation = ColorTween(
begin: beginColor,
end: endColor,
).animate(controller);
}
@override
@@ -37,9 +39,7 @@ class _AnimatedBuilderDemoState extends State<AnimatedBuilderDemo>
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AnimatedBuilder'),
),
appBar: AppBar(title: const Text('AnimatedBuilder')),
body: Center(
// AnimatedBuilder handles listening to a given animation and calling the builder
// whenever the value of the animation change. This can be useful when a Widget
@@ -49,9 +49,7 @@ class _AnimatedBuilderDemoState extends State<AnimatedBuilderDemo>
animation: animation,
builder: (context, child) {
return ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: animation.value,
),
style: ElevatedButton.styleFrom(backgroundColor: animation.value),
child: child,
onPressed: () {
switch (controller.status) {

View File

@@ -49,9 +49,7 @@ class _AnimatedContainerDemoState extends State<AnimatedContainerDemo> {
// the properties of a container. For example, you could use this to design expanding
// and shrinking cards.
return Scaffold(
appBar: AppBar(
title: const Text('AnimatedContainer'),
),
appBar: AppBar(title: const Text('AnimatedContainer')),
body: Center(
child: Column(
children: [
@@ -71,9 +69,7 @@ class _AnimatedContainerDemoState extends State<AnimatedContainerDemo> {
),
),
ElevatedButton(
child: const Text(
'change',
),
child: const Text('change'),
onPressed: () => change(),
),
],

View File

@@ -54,9 +54,7 @@ class _AnimationControllerDemoState extends State<AnimationControllerDemo>
// when building child widgets. You can also check the status to see if the animation
// has completed.
return Scaffold(
appBar: AppBar(
title: const Text('Animation Controller'),
),
appBar: AppBar(title: const Text('Animation Controller')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
@@ -79,7 +77,7 @@ class _AnimationControllerDemoState extends State<AnimationControllerDemo>
controller.forward();
}
},
)
),
],
),
),

View File

@@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
class TypewriterTween extends Tween<String> {
TypewriterTween({String begin = '', String end = ''})
: super(begin: begin, end: end);
: super(begin: begin, end: end);
@override
String lerp(double t) {
@@ -89,7 +89,9 @@ class _CustomTweenDemoState extends State<CustomTweenDemo>
return Text(
animation.value,
style: const TextStyle(
fontSize: 16, fontFamily: 'SpecialElite'),
fontSize: 16,
fontFamily: 'SpecialElite',
),
);
},
),

View File

@@ -30,10 +30,7 @@ class _FadeTransitionDemoState extends State<FadeTransitionDemo>
_curve = CurvedAnimation(parent: _controller, curve: Curves.easeIn);
_animation = Tween(
begin: 1.0,
end: 0.0,
).animate(_curve);
_animation = Tween(begin: 1.0, end: 0.0).animate(_curve);
}
@override
@@ -45,29 +42,25 @@ class _FadeTransitionDemoState extends State<FadeTransitionDemo>
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
'Fade Transition',
),
),
appBar: AppBar(title: const Text('Fade Transition')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
FadeTransition(
opacity: _animation,
child: const Icon(
Icons.star,
color: Colors.amber,
size: 300,
),
child: const Icon(Icons.star, color: Colors.amber, size: 300),
),
ElevatedButton(
child: const Text('animate'),
onPressed: () => setState(() {
_controller.animateTo(1.0).then<TickerFuture>(
(value) => _controller.animateBack(0.0));
}),
onPressed:
() => setState(() {
_controller
.animateTo(1.0)
.then<TickerFuture>(
(value) => _controller.animateBack(0.0),
);
}),
),
],
),

View File

@@ -11,9 +11,7 @@ class PageRouteBuilderDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Page 1'),
),
appBar: AppBar(title: const Text('Page 1')),
body: Center(
child: ElevatedButton(
child: const Text('Go!'),
@@ -30,8 +28,10 @@ Route _createRoute() {
return PageRouteBuilder<SlideTransition>(
pageBuilder: (context, animation, secondaryAnimation) => _Page2(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
var tween =
Tween<Offset>(begin: const Offset(0.0, 1.0), end: Offset.zero);
var tween = Tween<Offset>(
begin: const Offset(0.0, 1.0),
end: Offset.zero,
);
var curveTween = CurveTween(curve: Curves.ease);
return SlideTransition(
@@ -46,12 +46,12 @@ class _Page2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Page 2'),
),
appBar: AppBar(title: const Text('Page 2')),
body: Center(
child:
Text('Page 2!', style: Theme.of(context).textTheme.headlineMedium),
child: Text(
'Page 2!',
style: Theme.of(context).textTheme.headlineMedium,
),
),
);
}

View File

@@ -60,9 +60,7 @@ class _TweenSequenceDemoState extends State<TweenSequenceDemo>
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Tween Sequences'),
),
appBar: AppBar(title: const Text('Tween Sequences')),
body: Center(
child: AnimatedBuilder(
animation: animation,

View File

@@ -40,27 +40,25 @@ class _TweenDemoState extends State<TweenDemo>
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Tweens'),
),
appBar: AppBar(title: const Text('Tweens')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 200),
child: Text('\$${animation.value.toStringAsFixed(2)}',
style: const TextStyle(fontSize: 24)),
child: Text(
'\$${animation.value.toStringAsFixed(2)}',
style: const TextStyle(fontSize: 24),
),
),
ElevatedButton(
child: Text(
switch (controller.status) {
AnimationStatus.completed => 'Buy a Mansion',
AnimationStatus.forward => 'Accruing...',
AnimationStatus.reverse => 'Spending...',
_ => 'Win the lottery',
},
),
child: Text(switch (controller.status) {
AnimationStatus.completed => 'Buy a Mansion',
AnimationStatus.forward => 'Accruing...',
AnimationStatus.reverse => 'Spending...',
_ => 'Win the lottery',
}),
onPressed: () {
switch (controller.status) {
case AnimationStatus.completed:
@@ -69,7 +67,7 @@ class _TweenDemoState extends State<TweenDemo>
controller.forward();
}
},
)
),
],
),
),

View File

@@ -26,11 +26,11 @@ class _AnimatedListDemoState extends State<AnimatedListDemo> {
void addUser() {
setState(() {
var index = listData.length;
listData.add(
UserModel(++_maxIdValue, 'New', 'Person'),
listData.add(UserModel(++_maxIdValue, 'New', 'Person'));
_listKey.currentState!.insertItem(
index,
duration: const Duration(milliseconds: 300),
);
_listKey.currentState!
.insertItem(index, duration: const Duration(milliseconds: 300));
});
}
@@ -38,22 +38,22 @@ class _AnimatedListDemoState extends State<AnimatedListDemo> {
setState(() {
final index = listData.indexWhere((u) => u.id == id);
var user = listData.removeAt(index);
_listKey.currentState!.removeItem(
index,
(context, animation) {
return FadeTransition(
opacity: CurvedAnimation(
parent: animation, curve: const Interval(0.5, 1.0)),
child: SizeTransition(
sizeFactor: CurvedAnimation(
parent: animation, curve: const Interval(0.0, 1.0)),
axisAlignment: 0.0,
child: _buildItem(user),
_listKey.currentState!.removeItem(index, (context, animation) {
return FadeTransition(
opacity: CurvedAnimation(
parent: animation,
curve: const Interval(0.5, 1.0),
),
child: SizeTransition(
sizeFactor: CurvedAnimation(
parent: animation,
curve: const Interval(0.0, 1.0),
),
);
},
duration: const Duration(milliseconds: 600),
);
axisAlignment: 0.0,
child: _buildItem(user),
),
);
}, duration: const Duration(milliseconds: 600));
});
}
@@ -62,9 +62,7 @@ class _AnimatedListDemoState extends State<AnimatedListDemo> {
key: ValueKey<UserModel>(user),
title: Text(user.firstName),
subtitle: Text(user.lastName),
leading: const CircleAvatar(
child: Icon(Icons.person),
),
leading: const CircleAvatar(child: Icon(Icons.person)),
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () => deleteUser(user.id),
@@ -77,12 +75,7 @@ class _AnimatedListDemoState extends State<AnimatedListDemo> {
return Scaffold(
appBar: AppBar(
title: const Text('AnimatedList'),
actions: [
IconButton(
icon: const Icon(Icons.add),
onPressed: addUser,
),
],
actions: [IconButton(icon: const Icon(Icons.add), onPressed: addUser)],
),
body: SafeArea(
child: AnimatedList(
@@ -101,11 +94,7 @@ class _AnimatedListDemoState extends State<AnimatedListDemo> {
}
class UserModel {
UserModel(
this.id,
this.firstName,
this.lastName,
);
UserModel(this.id, this.firstName, this.lastName);
final int id;
final String firstName;

View File

@@ -54,10 +54,12 @@ class _AnimatedPositionedDemoState extends State<AnimatedPositionedDemo> {
left: leftPosition,
duration: const Duration(seconds: 1),
child: InkWell(
onTap: () => changePosition(
size.height -
(appBar.preferredSize.height + topPadding + 50),
size.width - 150),
onTap:
() => changePosition(
size.height -
(appBar.preferredSize.height + topPadding + 50),
size.width - 150,
),
child: Container(
alignment: Alignment.center,
width: 150,

View File

@@ -9,18 +9,18 @@ import 'package:flutter/material.dart';
Color generateColor() => Color(0xFFFFFFFF & Random().nextInt(0xFFFFFFFF));
Widget generateContainer(int keyCount) => Container(
key: ValueKey<int>(keyCount),
height: Random().nextDouble() * 200,
width: Random().nextDouble() * 200,
decoration: BoxDecoration(
color: generateColor(),
borderRadius: BorderRadius.circular(Random().nextDouble() * 100),
border: Border.all(
color: generateColor(),
width: Random().nextDouble() * 5,
),
),
);
key: ValueKey<int>(keyCount),
height: Random().nextDouble() * 200,
width: Random().nextDouble() * 200,
decoration: BoxDecoration(
color: generateColor(),
borderRadius: BorderRadius.circular(Random().nextDouble() * 100),
border: Border.all(
color: generateColor(),
width: Random().nextDouble() * 5,
),
),
);
class AnimatedSwitcherDemo extends StatefulWidget {
const AnimatedSwitcherDemo({super.key});
@@ -48,9 +48,8 @@ class _AnimatedSwitcherDemoState extends State<AnimatedSwitcherDemo> {
title: const Text('AnimatedSwitcher'),
actions: [
TextButton(
onPressed: () => setState(
() => container = generateContainer(++keyCount),
),
onPressed:
() => setState(() => container = generateContainer(++keyCount)),
child: const Text('Change Widget'),
),
],
@@ -62,10 +61,9 @@ class _AnimatedSwitcherDemoState extends State<AnimatedSwitcherDemo> {
child: AnimatedSwitcher(
duration: const Duration(seconds: 1),
child: container,
transitionBuilder: (child, animation) => ScaleTransition(
scale: animation,
child: child,
),
transitionBuilder:
(child, animation) =>
ScaleTransition(scale: animation, child: child),
),
),
);

View File

@@ -33,9 +33,7 @@ class _CardSwipeDemoState extends State<CardSwipeDemo> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Card Swipe'),
),
appBar: AppBar(title: const Text('Card Swipe')),
body: Padding(
padding: const EdgeInsets.all(12.0),
child: Center(
@@ -100,8 +98,11 @@ class SwipeableCard extends StatefulWidget {
final String imageAssetName;
final VoidCallback onSwiped;
const SwipeableCard(
{required this.onSwiped, required this.imageAssetName, super.key});
const SwipeableCard({
required this.onSwiped,
required this.imageAssetName,
super.key,
});
@override
State<SwipeableCard> createState() => _SwipeableCardState();
@@ -118,10 +119,9 @@ class _SwipeableCardState extends State<SwipeableCard>
void initState() {
super.initState();
_controller = AnimationController.unbounded(vsync: this);
_animation = _controller.drive(Tween<Offset>(
begin: Offset.zero,
end: const Offset(1, 0),
));
_animation = _controller.drive(
Tween<Offset>(begin: Offset.zero, end: const Offset(1, 0)),
);
}
@override
@@ -179,17 +179,26 @@ class _SwipeableCardState extends State<SwipeableCard>
}
void _updateAnimation(double dragPosition) {
_animation = _controller.drive(Tween<Offset>(
begin: Offset.zero,
end: _isSwipingLeft ? const Offset(-1, 0) : const Offset(1, 0),
));
_animation = _controller.drive(
Tween<Offset>(
begin: Offset.zero,
end: _isSwipingLeft ? const Offset(-1, 0) : const Offset(1, 0),
),
);
}
void _animate({double velocity = 0}) {
var description =
const SpringDescription(mass: 50, stiffness: 1, damping: 1);
var simulation =
SpringSimulation(description, _controller.value, 1, velocity);
var description = const SpringDescription(
mass: 50,
stiffness: 1,
damping: 1,
);
var simulation = SpringSimulation(
description,
_controller.value,
1,
velocity,
);
_controller.animateWith(simulation).then<void>((_) {
widget.onSwiped();
});

View File

@@ -21,9 +21,7 @@ class CarouselDemo extends StatelessWidget {
@override
Widget build(context) {
return Scaffold(
appBar: AppBar(
title: const Text('Carousel Demo'),
),
appBar: AppBar(title: const Text('Carousel Demo')),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16),
@@ -79,30 +77,29 @@ class _CarouselState extends State<Carousel> {
},
controller: _controller,
scrollBehavior: ScrollConfiguration.of(context).copyWith(
dragDevices: {
ui.PointerDeviceKind.touch,
ui.PointerDeviceKind.mouse,
},
dragDevices: {ui.PointerDeviceKind.touch, ui.PointerDeviceKind.mouse},
),
itemBuilder: (context, index) => AnimatedBuilder(
animation: _controller,
builder: (context, child) {
var result = _pageHasChanged ? _controller.page! : _currentPage * 1.0;
itemBuilder:
(context, index) => AnimatedBuilder(
animation: _controller,
builder: (context, child) {
var result =
_pageHasChanged ? _controller.page! : _currentPage * 1.0;
// The horizontal position of the page between a 1 and 0
var value = result - index;
value = (1 - (value.abs() * .5)).clamp(0.0, 1.0);
// The horizontal position of the page between a 1 and 0
var value = result - index;
value = (1 - (value.abs() * .5)).clamp(0.0, 1.0);
return Center(
child: SizedBox(
height: Curves.easeOut.transform(value) * size.height,
width: Curves.easeOut.transform(value) * size.width,
child: child,
),
);
},
child: widget.itemBuilder(context, index),
),
return Center(
child: SizedBox(
height: Curves.easeOut.transform(value) * size.height,
width: Curves.easeOut.transform(value) * size.width,
child: child,
),
);
},
child: widget.itemBuilder(context, index),
),
);
}

View File

@@ -46,10 +46,7 @@ class _CurvedAnimationDemoState extends State<CurvedAnimationDemo>
@override
void initState() {
super.initState();
controller = AnimationController(
duration: _duration,
vsync: this,
);
controller = AnimationController(duration: _duration, vsync: this);
selectedForwardCurve = curves[0];
selectedReverseCurve = curves[0];
curvedAnimation = CurvedAnimation(
@@ -57,38 +54,35 @@ class _CurvedAnimationDemoState extends State<CurvedAnimationDemo>
curve: selectedForwardCurve.curve,
reverseCurve: selectedReverseCurve.curve,
);
animationRotation = Tween<double>(
begin: 0,
end: 2 * math.pi,
).animate(curvedAnimation)
..addListener(() {
setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
}
});
animationTranslation = Tween<Offset>(
begin: const Offset(-1, 0),
end: const Offset(1, 0),
).animate(curvedAnimation)
..addListener(() {
setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
}
});
animationRotation =
Tween<double>(begin: 0, end: 2 * math.pi).animate(curvedAnimation)
..addListener(() {
setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
}
});
animationTranslation =
Tween<Offset>(
begin: const Offset(-1, 0),
end: const Offset(1, 0),
).animate(curvedAnimation)
..addListener(() {
setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.reverse();
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Curved Animation'),
),
appBar: AppBar(title: const Text('Curved Animation')),
body: Column(
children: [
const SizedBox(height: 20.0),
@@ -97,10 +91,13 @@ class _CurvedAnimationDemoState extends State<CurvedAnimationDemo>
style: Theme.of(context).textTheme.titleLarge,
),
DropdownButton<CurveChoice>(
items: curves.map((curve) {
return DropdownMenuItem<CurveChoice>(
value: curve, child: Text(curve.name));
}).toList(),
items:
curves.map((curve) {
return DropdownMenuItem<CurveChoice>(
value: curve,
child: Text(curve.name),
);
}).toList(),
onChanged: (newCurve) {
if (newCurve != null) {
setState(() {
@@ -117,10 +114,13 @@ class _CurvedAnimationDemoState extends State<CurvedAnimationDemo>
style: Theme.of(context).textTheme.titleLarge,
),
DropdownButton<CurveChoice>(
items: curves.map((curve) {
return DropdownMenuItem<CurveChoice>(
value: curve, child: Text(curve.name));
}).toList(),
items:
curves.map((curve) {
return DropdownMenuItem<CurveChoice>(
value: curve,
child: Text(curve.name),
);
}).toList(),
onChanged: (newCurve) {
if (newCurve != null) {
setState(() {
@@ -134,18 +134,12 @@ class _CurvedAnimationDemoState extends State<CurvedAnimationDemo>
const SizedBox(height: 35.0),
Transform.rotate(
angle: animationRotation.value,
child: const Center(
child: FlutterLogo(
size: 100,
),
),
child: const Center(child: FlutterLogo(size: 100)),
),
const SizedBox(height: 35.0),
FractionalTranslation(
translation: animationTranslation.value,
child: const FlutterLogo(
size: 100,
),
child: const FlutterLogo(size: 100),
),
const SizedBox(height: 25.0),
ElevatedButton(

View File

@@ -11,12 +11,8 @@ class ExpandCardDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Expandable Card'),
),
body: const Center(
child: ExpandCard(),
),
appBar: AppBar(title: const Text('Expandable Card')),
body: const Center(child: ExpandCard()),
);
}
}
@@ -56,24 +52,23 @@ class _ExpandCardState extends State<ExpandCard>
duration: duration,
firstCurve: Curves.easeInOutCubic,
secondCurve: Curves.easeInOutCubic,
crossFadeState: selected
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
crossFadeState:
selected
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
// Use Positioned.fill() to pass the constraints to its children.
// This allows the Images to use BoxFit.cover to cover the correct
// size
layoutBuilder:
(topChild, topChildKey, bottomChild, bottomChildKey) {
layoutBuilder: (
topChild,
topChildKey,
bottomChild,
bottomChildKey,
) {
return Stack(
children: [
Positioned.fill(
key: bottomChildKey,
child: bottomChild,
),
Positioned.fill(
key: topChildKey,
child: topChild,
),
Positioned.fill(key: bottomChildKey, child: bottomChild),
Positioned.fill(key: topChildKey, child: topChild),
],
);
},

View File

@@ -14,19 +14,15 @@ class FlutterAnimateDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Animate Demo'),
),
appBar: AppBar(title: const Text('Flutter Animate Demo')),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(
"Hello Flutter Animate",
style: Theme.of(context).textTheme.headlineLarge,
)
.animate(
onPlay: (controller) => controller.repeat(),
"Hello Flutter Animate",
style: Theme.of(context).textTheme.headlineLarge,
)
.animate(onPlay: (controller) => controller.repeat())
.then(delay: 250.ms)
.fadeIn(duration: 500.ms)
.then(delay: 250.ms)

View File

@@ -24,16 +24,15 @@ class Grid extends StatelessWidget {
return Scaffold(
body: GridView.builder(
itemCount: 40,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
),
itemBuilder: (context, index) {
return (index >= 20)
? const SmallCard(
imageAssetName: 'assets/eat_cape_town_sm.jpg',
)
? const SmallCard(imageAssetName: 'assets/eat_cape_town_sm.jpg')
: const SmallCard(
imageAssetName: 'assets/eat_new_orleans_sm.jpg',
);
imageAssetName: 'assets/eat_new_orleans_sm.jpg',
);
},
),
);
@@ -46,14 +45,12 @@ Route _createRoute(BuildContext parentContext, String image) {
return _SecondPage(image);
},
transitionsBuilder: (context, animation, secondaryAnimation, child) {
var rectAnimation = _createTween(parentContext)
.chain(CurveTween(curve: Curves.ease))
.animate(animation);
var rectAnimation = _createTween(
parentContext,
).chain(CurveTween(curve: Curves.ease)).animate(animation);
return Stack(
children: [
PositionedTransition(rect: rectAnimation, child: child),
],
children: [PositionedTransition(rect: rectAnimation, child: child)],
);
},
);
@@ -65,10 +62,7 @@ Tween<RelativeRect> _createTween(BuildContext context) {
var rect = box.localToGlobal(Offset.zero) & box.size;
var relativeRect = RelativeRect.fromSize(rect, windowSize);
return RelativeRectTween(
begin: relativeRect,
end: RelativeRect.fill,
);
return RelativeRectTween(begin: relativeRect, end: RelativeRect.fill);
}
class SmallCard extends StatelessWidget {
@@ -84,10 +78,7 @@ class SmallCard extends StatelessWidget {
var nav = Navigator.of(context);
nav.push<void>(_createRoute(context, imageAssetName));
},
child: Image.asset(
imageAssetName,
fit: BoxFit.cover,
),
child: Image.asset(imageAssetName, fit: BoxFit.cover),
),
),
);
@@ -109,10 +100,7 @@ class _SecondPage extends StatelessWidget {
onTap: () => Navigator.of(context).pop(),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset(
imageAssetName,
fit: BoxFit.cover,
),
child: Image.asset(imageAssetName, fit: BoxFit.cover),
),
),
),

View File

@@ -11,19 +11,16 @@ class HeroAnimationDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Hero Animation'),
),
appBar: AppBar(title: const Text('Hero Animation')),
body: GestureDetector(
child: Hero(
tag: 'hero-page-child',
child: _createHeroContainer(
size: 50.0,
color: Colors.grey.shade300,
),
child: _createHeroContainer(size: 50.0, color: Colors.grey.shade300),
),
onTap: () => Navigator.of(context).push<void>(
MaterialPageRoute(builder: (context) => const HeroPage())),
onTap:
() => Navigator.of(context).push<void>(
MaterialPageRoute(builder: (context) => const HeroPage()),
),
),
);
}
@@ -40,10 +37,7 @@ class HeroPage extends StatelessWidget {
body: Center(
child: Hero(
tag: 'hero-page-child',
child: _createHeroContainer(
size: 100.0,
color: Colors.white,
),
child: _createHeroContainer(size: 100.0, color: Colors.white),
),
),
);
@@ -59,10 +53,7 @@ StatelessWidget _createHeroContainer({
width: size,
padding: const EdgeInsets.all(10.0),
margin: size < 100.0 ? const EdgeInsets.all(10.0) : const EdgeInsets.all(0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: color,
),
decoration: BoxDecoration(shape: BoxShape.circle, color: color),
child: const FlutterLogo(),
);
}

View File

@@ -12,14 +12,8 @@ class PhysicsCardDragDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Spring Physics'),
),
body: const DraggableCard(
child: FlutterLogo(
size: 128,
),
),
appBar: AppBar(title: const Text('Spring Physics')),
body: const DraggableCard(child: FlutterLogo(size: 128)),
);
}
}
@@ -67,14 +61,15 @@ class _DraggableCardState extends State<DraggableCard>
/// Calculates and runs a [SpringSimulation]
void _runAnimation(Offset velocity, Size size) {
_animation = _controller.drive(
AlignmentTween(
begin: _dragAlignment,
end: Alignment.center,
),
AlignmentTween(begin: _dragAlignment, end: Alignment.center),
);
final simulation =
SpringSimulation(_spring, 0, 1, _normalizeVelocity(velocity, size));
final simulation = SpringSimulation(
_spring,
0,
1,
_normalizeVelocity(velocity, size),
);
_controller.animateWith(simulation);
}
@@ -97,20 +92,17 @@ class _DraggableCardState extends State<DraggableCard>
final size = MediaQuery.of(context).size;
return GestureDetector(
onPanStart: (details) => _controller.stop(canceled: true),
onPanUpdate: (details) => setState(
() => _dragAlignment += Alignment(
details.delta.dx / (size.width / 2),
details.delta.dy / (size.height / 2),
),
),
onPanEnd: (details) =>
_runAnimation(details.velocity.pixelsPerSecond, size),
child: Align(
alignment: _dragAlignment,
child: Card(
child: widget.child,
),
),
onPanUpdate:
(details) => setState(
() =>
_dragAlignment += Alignment(
details.delta.dx / (size.width / 2),
details.delta.dy / (size.height / 2),
),
),
onPanEnd:
(details) => _runAnimation(details.velocity.pixelsPerSecond, size),
child: Align(alignment: _dragAlignment, child: Card(child: widget.child)),
);
}
}

View File

@@ -21,9 +21,10 @@ class _RepeatingAnimationDemoState extends State<RepeatingAnimationDemo>
void initState() {
super.initState();
_controller =
AnimationController(duration: const Duration(seconds: 2), vsync: this)
..repeat(reverse: true);
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat(reverse: true);
_borderRadius = BorderRadiusTween(
begin: BorderRadius.circular(100.0),