今天會開始介紹flutter cookbook的內容,flutter cookbook是一連串進階技術的教學,我會先從flutter動畫開始介紹
PageRouteBuilder
提供了一個Animation
物件。Animation
可與Tween
和Curve
物件一起使用以客製化過場動畫。
首先,使用PageRouteBuilder創建一個路線。PageRouteBuilder有兩個callback,一個用於構建路線的內容(pageBuilder),一個用於構建路線的轉換(transitionsBuilder)
以下範例創建了兩條路線:一條帶有“Go!”的 home 路線。按鈕,以及標題為“Page 2”的第二條路線。
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Page1(),
),
);
}
class Page1 extends StatelessWidget {
const Page1({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(_createRoute());
},
child: const Text('Go!'),
),
),
);
}
}
Route _createRoute() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => const Page2(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return child;
},
);
}
class Page2 extends StatelessWidget {
const Page2({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: const Center(
child: Text('Page 2'),
),
);
}
}
將PageRouteBuilder設定好後要創建Tween,要使新頁面的動畫從底部往上出現,應該設定為從 Offset(0,1) 到 Offset(0, 0)
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
final tween = Tween(begin: begin, end: end);
final offsetAnimation = animation.drive(tween);
return child;
},
Flutter 有一組繼承AnimatedWidget的widget,當動畫中的值發生變化時,它們會重新rebuild並顯示。例如,SlideTransition 採用 Animation 並在動畫值發生變化時轉換其子類(使用 FractionalTranslation widget)。
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
final tween = Tween(begin: begin, end: end);
final offsetAnimation = animation.drive(tween);
return SlideTransition(
position: offsetAnimation,
child: child,
);
},
Flutter 提供了一系列curve,可以隨時間調整動畫的速率。Curves 類提供了一組預定義的常用曲線。例如,Curves.easeOut
使動畫快速開始並緩慢結束。
var curve = Curves.ease;
var curveTween = CurveTween(curve: curve);
使用chain()
結合上述提到的兩種Tween
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
然後通過將它傳遞給animation.drive()創建一個新的 Animation 可以提供給 SlideTransition widget
return SlideTransition(
position: animation.drive(tween),
child: child,
);
參考資料:
https://docs.flutter.dev/cookbook/animation/page-route-animation