Flutterのページ間を移動するときにデフォルトのアニメーションを変更する方法はありますか?
CupertinoPageRoute を使用してこれを実現できます。以下のコードを確認してください。
import 'package:flutter/material.Dart';
import 'package:flutter/cupertino.Dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Transition Animation Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new FirstPage(),
);
}
}
class FirstPage extends StatefulWidget {
@override
_FirstPageState createState() => new _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('First Page'),
),
body: new Center(
child: new RaisedButton(
child: new Text('Goto Second Page'),
onPressed: () {
Navigator.of(context).Push(new SecondPageRoute());
},
),
),
);
}
}
class SecondPageRoute extends CupertinoPageRoute {
SecondPageRoute()
: super(builder: (BuildContext context) => new SecondPage());
// OPTIONAL IF YOU WISH TO HAVE SOME EXTRA ANIMATION WHILE ROUTING
@override
Widget buildPage(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return new FadeTransition(opacity: animation, child: new SecondPage());
}
}
class SecondPage extends StatefulWidget {
@override
_SecondPageState createState() => new _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Second Page'),
),
body: new Center(
child: new Text('This is the second page'),
),
);
}
}
アニメーションの一部の再生(
// OPTIONAL IF YOU WISH TO HAVE SOME EXTRA ANIMATION WHILE ROUTING
@override
Widget buildPage(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return new RotationTransition(
turns: animation,
child: new ScaleTransition(
scale: animation,
child: new FadeTransition(
opacity: animation,
child: new SecondPage(),
),
));
}
MaterialPageRoute をサブクラス化して、buildTransitionsをオーバーライドできます。
例えば:
class MyCustomRoute<T> extends MaterialPageRoute<T> {
MyCustomRoute({ WidgetBuilder builder, RouteSettings settings })
: super(builder: builder, settings: settings);
@override
Widget buildTransitions(BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
if (settings.isInitialRoute)
return child;
// Fades between routes. (If you don't want any animation,
// just return child.)
return new FadeTransition(opacity: animation, child: child);
}
}
使用する:
new RaisedButton(
child: new Text('Goto'),
onPressed: (){
Navigator.Push(
context,
new MyCustomRoute(builder: (context) => new SecondPage()),
);
}),
フェードトランジションをアニメーションに置き換えます
アプリレベルのテーマ用にbuilders
に独自のpageTransitionsTheme
のカスタムマップを提供して、.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Startup Name Generator Tile',
home: RandomWords(),
theme: new ThemeData(
primaryColor: Colors.white,
// Add the line below to get horizontal sliding transitions for routes.
pageTransitionsTheme: PageTransitionsTheme(builders: {TargetPlatform.Android: CupertinoPageTransitionsBuilder(),}),
),
);
}
}
もちろん、TargetPlatform
にはAndroidのみを使用するため、iosのマップエントリは追加しませんでした。
PageRouteBuilder
を使用できます。
次の例は、2番目の画面に移動したときのFadeTransition
を示しています。
Navigator.Push(
context,
PageRouteBuilder(
pageBuilder: (c, a1, a2) => Page2(),
transitionsBuilder: (c, anim, a2, child) => FadeTransition(opacity: anim, child: child),
transitionDuration: Duration(milliseconds: 2000),
),
);