La traduction a été préparée dans le cadre du cours « Flutter Mobile Developer » .
Nous invitons tous les arrivants à la deuxième journée de l'intensif en ligne de deux jours «Nous créons une application sur Flutter pour le Web, iOS et Android» . Nous continuons à écrire l'application (ce sera une application réseau: chargement d'une liste d'entités + filtrage de celles-ci + création d'un bloc de paramètres dans l'application, où vous pourrez changer le thème de l'application (couleurs)). Rejoignez-nous!

Quand j'ai vu le widget pour la première fois AnimationSwitcher
, j'ai pensé que je pouvais le retourner en ouvrant son dos.

Je me suis trompé: AnimationSwitcher
permet ... de basculer entre différents widgets avec l'animation que vous avez spécifiée (l'animation par défaut est une transition de fondu). Ce composant est trop polyvalent à cet effet.

, , .
flutter, -, animated_card_switcher, , , , .
:
AnimationSwitcher
.
, .
, , , , AnimationSwitcher
, (, , ).

, :
Widget __buildLayout({Key key, String faceName, Color backgroundColor}) {
return Container(
key: key,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(20.0),
color: backgroundColor,
),
child: Center(
child: Text(faceName.substring(0, 1), style: TextStyle(fontSize: 80.0)),
),
);
, :
Widget _buildFront() {
return __buildLayout(
key: ValueKey(true),
backgroundColor: Colors.blue,
faceName: "F",
);
}
Widget _buildRear() {
return __buildLayout(
key: ValueKey(false),
backgroundColor: Colors.blue.shade700,
faceName: "R",
);
}
AnimationSwitcher
AnimationSwitcher
.
StatefulWidget
build
, , .
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _displayFront;
bool _flipXAxis;
@override
void initState() {
super.initState();
_displayFront = true;
_flipXAxis = true;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(this.widget.title),
centerTitle: true,
),
body: Center(
child: Container(
constraints: BoxConstraints.tight(Size.square(200.0)),
child: _buildFlipAnimation(),
),
);
}
}
_build Flip Animation
, .
:
Widget _buildFlipAnimation() {
return GestureDetector(
onTap: () => setState(() =>_showFrontSide = !_showFrontSide),
child: AnimatedSwitcher(
duration: Duration(milliseconds: 600),
child: _showFrontSide ? _buildFront() : _buildRear(),
),
);
}
, , , . , .

Y. , AnimationSwitcher
, transitionBuilder
.
, : 180° (pi). AnimatedBuidler
Transform
.
Widget __transitionBuilder(Widget widget, Animation<double> animation) {
final rotateAnim = Tween(begin: pi, end: 0.0).animate(animation);
return AnimatedBuilder(
animation: rotateAnim,
child: widget,
builder: (context, widget) {
return Transform(
transform: Matrix4.rotationY(value),
child: widget,
alignment: Alignment.center,
);
},
);
}

, , . , .

, .
:
: .
.
layoutBuilder
AnimationSwitcher
.
layoutBuilder: (widget, list) => Stack(children: [widget, ...list]),
, , pi/2 0.0. () .
Widget __transitionBuilder(Widget widget, Animation<double> animation) {
final rotateAnim = Tween(begin: pi, end: 0.0).animate(animation);
return AnimatedBuilder(
animation: rotateAnim,
child: widget,
builder: (context, widget) {
final isUnder = (ValueKey(_showFrontSide) != widget.key);
final value = isUnder ? min(rotateAnim.value, pi / 2) : rotateAnim.value;
return Transform(
transform: Matrix4.rotationY(value),
child: widget,
alignment: Alignment.center,
);
},
);
}

, ! , , "tilt" () .

"" 0,0 . , , . , 0,2, -0,2.
, Matrix4, .
Widget __transitionBuilder(Widget widget, Animation<double> animation) {
final rotateAnim = Tween(begin: pi, end: 0.0).animate(animation);
return AnimatedBuilder(
animation: rotateAnim,
child: widget,
builder: (context, widget) {
final isUnder = (ValueKey(_showFrontSide) != widget.key);
var tilt = ((animation.value - 0.5).abs() - 0.5) * 0.003;
tilt *= isUnder ? -1.0 : 1.0;
final value = isUnder ? min(rotateAnim.value, pi / 2) : rotateAnim.value;
return Transform(
transform: Matrix4.rotationY(value)..setEntry(3, 0, tilt),
child: widget,
alignment: Alignment.center,
);
},
);
}
Matrix4 : https://medium.com/flutter-community/advanced-flutter-matrix4-and-perspective-transformations-a79404a0d828.
, , AnimationSwitcher.

:
Widget _buildFlipAnimation() {
return GestureDetector(
onTap: _switchCard,
child: AnimatedSwitcher(
duration: Duration(milliseconds: 4600),
transitionBuilder: __transitionBuilder,
layoutBuilder: (widget, list) => Stack(children: [widget, ...list]),
child: _showFrontSide ? _buildFront() : _buildRear(),
switchInCurve: Curves.easeInBack,
switchOutCurve: Curves.easeOutBack,
),
);
}
.

, , , . .

, flipped
, .
switchInCurve: Curves.easeInBack, switchOutCurve: Curves.easeInBack.flipped,

, : 30 ( ), ( ).
, . , (), . , , , 6 , 1 2 ...

. , ( ) “ ”, - , !
, , .
Flutter Twitter
"Flutter Mobile Developer"
- « Flutter Web, iOS Android»