Flutter Web中PageView切换页面实现FadeTransition淡入淡出效果问题咨询
问题解决方案
核心问题原因
- 初始白屏:动画初始值为0,绑定了FadeTransition的页面首次加载时透明度为0,没有触发动画播放,因此完全透明
- 滑动不生效:PageView设置了
NeverScrollableScrollPhysics,本身无法响应用户滑动操作,滚动通知回调完全不会被触发 - 逻辑冲突:滚动通知会被滑动过程多次触发,重复调用页面切换和动画播放方法,导致页面闪烁、跳转异常
修复后可直接运行的代码
import 'package:flutter/material.dart'; class TestLayout extends StatefulWidget { const TestLayout({Key? key}) : super(key: key); @override _TestLayoutState createState() => _TestLayoutState(); } class _TestLayoutState extends State<TestLayout> { final PageController pageController = PageController(); @override void dispose() { pageController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( extendBodyBehindAppBar: true, appBar: MediaQuery.of(context).size.width > 760 ? null : AppBar( elevation: 0.0, backgroundColor: Colors.transparent, ), body: PageView.builder( controller: pageController, scrollDirection: Axis.vertical, itemCount: 2, itemBuilder: (context, index) { return AnimatedBuilder( animation: pageController, builder: (context, child) { double opacity = 1.0; if (pageController.position.haveDimensions) { // 计算当前页面和相邻页面的透明度 opacity = pageController.page! - index; opacity = 1 - (opacity.abs().clamp(0, 1)); } return Opacity( opacity: opacity, child: child, ); }, child: [ Container(color: Colors.red, child: const Center(child: Text("Hi"))), Container(color: Colors.yellow, child: const Center(child: Text("Welcome"))) ][index], ); }, ), ); } }
实现说明
- 直接通过PageController的滚动偏移动态计算页面透明度,滑动过程中自动实现淡入淡出过渡,无需手动维护动画控制器
- 保留了PageView原生的滑动手感,不会出现滑动冲突、反复触发的问题
- 首次加载时默认显示第一个页面,没有白屏问题
- 支持Web、移动端多平台运行
内容的提问来源于stack exchange,提问作者user10033434
相关产品推荐
相关产品推荐

