如何在Flutter中创建动画PageView及曲线页面动画效果?
Flutter 动画 PageView 及曲线页面动画实现
一、基础动画 PageView 实现
普通的动画 PageView 可以通过结合 PageController 和动画控制器实现页面切换过渡,或是用自带组件实现丰富切换效果,以下是两种常用方式:
方式1:PageController 配合动画控制页面切换
class AnimatedPageView extends StatefulWidget { const AnimatedPageView({super.key}); @override State<AnimatedPageView> createState() => _AnimatedPageViewState(); } class _AnimatedPageViewState extends State<AnimatedPageView> with SingleTickerProviderStateMixin { late PageController _pageController; late AnimationController _animationController; late Animation<double> _animation; @override void initState() { super.initState(); _pageController = PageController(initialPage: 0); _animationController = AnimationController( duration: const Duration(milliseconds: 300), vsync: this, ); _animation = CurvedAnimation(parent: _animationController, curve: Curves.easeInOut); } void _switchPage(int page) { _animationController.reset(); _animationController.forward(); _pageController.animateToPage( page, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); } @override Widget build(BuildContext context) { return Scaffold( body: PageView( controller: _pageController, children: const [ Center(child: Text("页面1")), Center(child: Text("页面2")), Center(child: Text("页面3")), ], ), bottomNavigationBar: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton(onPressed: () => _switchPage(0), child: const Text("去页面1")), ElevatedButton(onPressed: () => _switchPage(1), child: const Text("去页面2")), ElevatedButton(onPressed: () => _switchPage(2), child: const Text("去页面3")), ], ), ); } @override void dispose() { _pageController.dispose(); _animationController.dispose(); super.dispose(); } }
方式2:PageTransitionSwitcher 搭配 PageView
如果需要淡入淡出、缩放等更丰富的切换动画,可用 PageTransitionSwitcher 包裹页面:
class TransitionPageView extends StatefulWidget { const TransitionPageView({super.key}); @override State<TransitionPageView> createState() => _TransitionPageViewState(); } class _TransitionPageViewState extends State<TransitionPageView> { int _currentPage = 0; final PageController _pageController = PageController(); @override Widget build(BuildContext context) { return Scaffold( body: PageTransitionSwitcher( duration: const Duration(milliseconds: 500), transitionBuilder: (child, animation, secondaryAnimation) { return FadeTransition( opacity: animation, child: ScaleTransition( scale: animation, child: child, ), ); }, child: PageView( controller: _pageController, onPageChanged: (index) => setState(() => _currentPage = index), children: List.generate(3, (index) => Center(child: Text("页面${index+1}", key: ValueKey(index)))), ), ), ); } }
二、曲线页面动画效果的 PageView 实现
你提供的参考效果(如下方图片所示)是页面切换时带弧度变形的曲线动画,核心是根据页面偏移量计算变换参数,结合 Transform 和 AnimatedBuilder 实现:

以下是实现代码:
class CurvedPageView extends StatefulWidget { const CurvedPageView({super.key}); @override State<CurvedPageView> createState() => _CurvedPageViewState(); } class _CurvedPageViewState extends State<CurvedPageView> { final PageController _pageController = PageController(viewportFraction: 0.8); @override Widget build(BuildContext context) { return Scaffold( body: PageView.builder( controller: _pageController, itemCount: 5, itemBuilder: (context, index) { return AnimatedBuilder( animation: _pageController, builder: (context, child) { double value = 1.0; if (_pageController.position.haveDimensions) { // 获取当前页面的偏移比例 value = _pageController.page! - index; value = (1 - (value.abs() * 0.3)).clamp(0.0, 1.0); } // 用Matrix4实现曲线变形效果 return Transform( transform: Matrix4.identity() ..setEntry(3, 2, 0.001) ..rotateY(value * 0.3) ..scale(value), alignment: Alignment.center, child: child, ); }, child: Container( margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), color: Colors.primaries[index % Colors.primaries.length], ), child: Center(child: Text("页面${index+1}", style: const TextStyle(fontSize: 24, color: Colors.white))), ), ); }, ), ); } }
关键说明:
viewportFraction: 0.8:设置页面宽度占视口的80%,让相邻页面部分显示,强化曲线效果的视觉层次感AnimatedBuilder:监听PageController滚动状态,实时更新页面变换参数Matrix4:通过旋转、缩放和透视变换模拟曲线弯曲效果,可调整rotateY、scale等参数适配需求
内容的提问来源于stack exchange,提问作者Rushikesh Bhayani
相关产品推荐
相关产品推荐

