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

Add animation samples (#118)

* initialize animations sample project

* add two demos, set up routing

* clean up expand_card demo

* update README

* clean up expand_card demo

* dartfmt

* update comment

* address code review comments

* swap AnimatedContainer and AnimatedCrossFade

* use AnimatedSwitcher instead of AnimatedCrossFade

* Revert "use AnimatedSwitcher instead of AnimatedCrossFade"

This reverts commit e112e02549.

* rename expanded -> selected

* use  Dart 2.4.0 constraint

* update README

* address code review comments

update images
add curves to expand_card
update pubspec.lock

* add @override annotation

* add animations project to travis script

* add empty test for travis

* add copyright notice to animations/ project
This commit is contained in:
John Ryan
2019-07-23 15:51:57 -07:00
committed by GitHub
parent 086a77b1b8
commit 2d42fcfd31
66 changed files with 1650 additions and 0 deletions

85
animations/lib/main.dart Normal file
View File

@@ -0,0 +1,85 @@
// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'src/basics/animation_controller_demo.dart';
import 'src/misc/expand_card.dart';
void main() => runApp(AnimationSamples());
class Demo {
final String name;
final String route;
final WidgetBuilder builder;
const Demo(this.name, this.route, this.builder);
}
final basicDemos = [
Demo('Animation Controller', AnimationControllerDemo.routeName,
(context) => AnimationControllerDemo()),
];
final miscDemos = [
Demo('Expandable Card', ExpandCardDemo.routeName,
(context) => ExpandCardDemo()),
];
final basicDemoRoutes =
Map.fromEntries(basicDemos.map((d) => MapEntry(d.route, d.builder)));
final miscDemoRoutes =
Map.fromEntries(miscDemos.map((d) => MapEntry(d.route, d.builder)));
final allRoutes = <String, WidgetBuilder>{
...basicDemoRoutes,
...miscDemoRoutes,
};
class AnimationSamples extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Animation Samples',
theme: ThemeData(
primarySwatch: Colors.deepPurple,
),
routes: allRoutes,
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
Widget build(BuildContext context) {
final headerStyle = Theme.of(context).textTheme.title;
return Scaffold(
appBar: AppBar(
title: Text('Animation Samples'),
),
body: ListView(
children: [
ListTile(title: Text('Basics', style: headerStyle)),
...basicDemos.map((d) => DemoTile(d)),
ListTile(title: Text('Misc', style: headerStyle)),
...miscDemos.map((d) => DemoTile(d)),
],
),
);
}
}
class DemoTile extends StatelessWidget {
final Demo demo;
DemoTile(this.demo);
Widget build(BuildContext context) {
return ListTile(
title: Text(demo.name),
onTap: () {
Navigator.pushNamed(context, demo.route);
},
);
}
}

View File

@@ -0,0 +1,67 @@
// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
class AnimationControllerDemo extends StatefulWidget {
static const String routeName = '/basics/animation_controller';
@override
_AnimationControllerDemoState createState() =>
_AnimationControllerDemoState();
}
class _AnimationControllerDemoState extends State<AnimationControllerDemo>
with SingleTickerProviderStateMixin {
static const Duration _duration = Duration(seconds: 1);
AnimationController controller;
@override
void initState() {
super.initState();
controller = AnimationController(vsync: this, duration: _duration)
..addListener(() {
// Force build() to be called again
setState(() {});
});
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ConstrainedBox(
constraints: BoxConstraints(maxWidth: 200),
child: Text(
'${controller.value.toStringAsFixed(2)}',
style: Theme.of(context).textTheme.display3,
),
),
RaisedButton(
child: Text('animate'),
onPressed: () {
if (controller.status == AnimationStatus.completed) {
controller.reverse();
} else {
controller.forward();
}
},
)
],
),
),
);
}
}

View File

@@ -0,0 +1,89 @@
// Copyright 2019 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
class ExpandCardDemo extends StatelessWidget {
static const String routeName = '/expand_card';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: ExpandCard(),
),
);
}
}
class ExpandCard extends StatefulWidget {
_ExpandCardState createState() => _ExpandCardState();
}
class _ExpandCardState extends State<ExpandCard>
with SingleTickerProviderStateMixin {
static const Duration duration = Duration(milliseconds: 300);
bool selected = false;
double get size => selected ? 256 : 128;
void toggleExpanded() {
setState(() {
selected = !selected;
});
}
@override
Widget build(context) {
return GestureDetector(
onTap: () => toggleExpanded(),
child: Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: AnimatedContainer(
duration: duration,
width: size,
height: size,
curve: Curves.ease,
child: AnimatedCrossFade(
duration: duration,
firstCurve: Curves.easeInOutCubic,
secondCurve: Curves.easeInOutCubic,
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) {
return Stack(
children: <Widget>[
Positioned.fill(
key: bottomChildKey,
child: bottomChild,
),
Positioned.fill(
key: topChildKey,
child: topChild,
),
],
);
},
firstChild: Image.asset(
'assets/eat_cape_town_sm.jpg',
fit: BoxFit.cover,
),
secondChild: Image.asset(
'assets/eat_new_orleans_sm.jpg',
fit: BoxFit.cover,
),
),
),
),
),
);
}
}