Flutter如何跨页面访问PageController实现PageView指定页面跳转
实现方案
核心逻辑是通过路由传参把目标页码从ScreenA传递给ScreenB,不要直接跨页面访问另一个页面的私有PageController,既违反封装原则也容易出现生命周期相关的异常,具体修改如下:
1. 修改ScreenA的点击跳转逻辑
把原来直接调用_pageController的逻辑,替换为跳转ScreenB时携带页码参数:
class ScreenA extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey[200], body: SafeArea(child: ListView( children: [ for (int i = 0; i < 5; i++) TextButton( onPressed: (){ // 跳转ScreenB时携带目标页码参数 Navigator.push(context, MaterialPageRoute(builder: (context)=> ScreenB(initialPage: i))); }, child: Container( child: Text("点击跳转到第$i页"), ), ) ], ), ), ); } }
2. 修改ScreenB接收参数并初始化页面
给ScreenB增加接收初始页码的属性,通过参数控制PageController的初始位置:
// 先修改ScreenB的Widget类定义,新增initialPage参数 class ScreenB extends StatefulWidget { // 接收从ScreenA传过来的目标页码,默认值设为0 final int initialPage; const ScreenB({super.key, this.initialPage = 0}); @override State<ScreenB> createState() => _ScreenBState(); } class _ScreenBState extends State<ScreenB> { late PageController _pageController; @override void initState() { super.initState(); // 方案1:不需要跳转动画,直接指定初始化页码,性能最优 _pageController = PageController(initialPage: widget.initialPage); // 方案2:需要保留400ms跳转动画,用下面的代码替代上面的初始化逻辑即可 // _pageController = PageController(); // WidgetsBinding.instance.addPostFrameCallback((_) { // _pageController.animateToPage( // widget.initialPage, // duration: const Duration(milliseconds: 400), // curve: Curves.easeInOut, // ); // }); } @override void dispose() { // 销毁控制器释放资源,避免内存泄漏 _pageController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey[200], body: SafeArea( child: PageView( controller: _pageController, children: [ for (int i = 0; i < 5; i++) Container( color: i%2 ==0 ? Colors.red : Colors.blue, child: Center( child: Text("第$i页内容"), ), ), ], ), ), ); } }
内容的提问来源于stack exchange,提问作者shakky
相关产品推荐
相关产品推荐

