You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 03:36:04