Flutter PageView滑动时如何实现文本进出动画及设置触发点
实现思路
你已经在使用PageController处理图片滚动逻辑,可以直接复用该控制器的状态驱动文本动画,无需额外引入复杂的监听逻辑。
方案1:文本动画跟随滚动实时联动
适合需要和滑动手势强绑定的丝滑过渡效果:
- 首先监听
PageController的滚动状态,获取当前滚动进度final PageController _pageController = PageController(); // 存储当前滚动的页面进度,滑到第n页到n+1页之间时,值从n平滑过渡到n+1 double _currentPage = 0; @override void initState() { super.initState(); _pageController.addListener(() { setState(() { _currentPage = _pageController.page ?? 0; }); }); } - 针对每个页面的文本组件,通过当前进度和页面索引的差值计算动画参数
以第index页的文本为例,滑入时从右侧平移+渐显,滑出时向左侧平移+渐隐的实现如下:// 计算当前页面对应的动画进度,值范围固定在0~1之间 final animProgress = (_currentPage - index).clamp(0.0, 1.0); Opacity( // 进度为0时完全显示,进度为1时完全隐藏 opacity: 1 - animProgress, child: Transform.translate( // 滑入时从右侧100dp位置移动到原点,滑出时向左侧移动100dp offset: Offset(animProgress * 100, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: const [ Text('引导页标题', style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600)), SizedBox(height: 12), Text('引导页描述内容', style: TextStyle(fontSize: 16, color: Colors.grey)), ], ), ), )
方案2:页面切换完成后触发固定动画
适合不需要跟随滚动联动,仅在页面完全选中后播放文本入场动画的场景:
- 初始化每个页面对应的文本动画控制器
// 假设引导页总共有3页,每个页面对应一个独立的动画控制器 late List<AnimationController> _textAnimControllers; late List<Animation<Offset>> _slideAnims; late List<Animation<double>> _fadeAnims; @override void initState() { super.initState(); _textAnimControllers = List.generate(3, (index) => AnimationController( vsync: this, duration: const Duration(milliseconds: 500), )); // 平移动画:从下方30dp位置上移到原点 _slideAnims = _textAnimControllers.map((controller) => Tween<Offset>( begin: const Offset(0, 30), end: Offset.zero, ).animate(CurvedAnimation(parent: controller, curve: Curves.easeOut))).toList(); // 渐变动画:从完全透明到完全显示 _fadeAnims = _textAnimControllers.map((controller) => Tween<double>( begin: 0, end: 1, ).animate(CurvedAnimation(parent: controller, curve: Curves.easeOut))).toList(); } - 绑定
PageView的页面切换回调作为动画触发点PageView( controller: _pageController, onPageChanged: (index) { // 重置所有页面的动画状态 for (var controller in _textAnimControllers) { controller.reset(); } // 触发当前选中页面的文本入场动画 _textAnimControllers[index].forward(); }, children: [], ) - 给每个页面的文本绑定动画
// 第index页的文本组件 FadeTransition( opacity: _fadeAnims[index], child: SlideTransition( position: _slideAnims[index], child: 你的文本组件, ), ) - 页面销毁时释放所有控制器资源
@override void dispose() { _pageController.dispose(); for (var controller in _textAnimControllers) { controller.dispose(); } super.dispose(); }
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

