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

Flutter底部导航栏自定义双按钮控制PageView4个页面并添加页码计数器

实现方案

你不需要使用系统自带的BottomNavigationBar组件,直接自定义底部导航布局即可,修改逻辑如下:

  1. 替换底部导航组件:将AnimatedBuilder中返回的BottomNavigationBar替换为自定义的Container+Row布局,分别承载左箭头、计数器、右箭头三个元素
  2. 实现页面切换逻辑:左箭头点击时判断当前页码是否大于0,满足条件则跳转上一页;右箭头点击时判断当前页码是否小于3(4个页面对应索引0~3),满足条件则跳转下一页;边界状态下对应按钮置灰不可点击
  3. 实现计数器展示:直接通过监听的pageViewController获取当前页码,拼接为当前页/总页数的格式展示即可

修改后的完整代码示例:

class _CreateAccountPageState
  extends ModularState<CreateAccountPage, CreateAccountController> {
      // 总页面数常量,后续调整页面数量直接修改这里即可
      static const totalPage = 4;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: PageView(
              controller: controller.pageViewController,
              // 禁止手动滑动页面,只允许按钮控制,不需要该功能可以删掉这行
              physics: const NeverScrollableScrollPhysics(),
              children: const [
                RouterOutlet(),
                RouterOutlet(),
                RouterOutlet(),
                RouterOutlet()
              ],
            ),
            bottomNavigationBar: AnimatedBuilder(
              animation: controller.pageViewController,
              builder: (context, snapshot) {
                // 获取当前页码
                final currentPage = controller.pageViewController.page?.round() ?? 0;
                return Container(
                  padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
                  color: Colors.white,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      // 左箭头按钮
                      IconButton(
                        onPressed: currentPage > 0 ? () {
                          // 切换到上一页
                          controller.pageViewController.previousPage(
                            duration: const Duration(milliseconds: 300), 
                            curve: Curves.easeInOut
                          );
                          // 同步Modular路由
                          Modular.to.navigate('/createaccount/pageStep${currentPage}');
                        } : null,
                        icon: Icon(
                          Icons.arrow_back_ios,
                          color: currentPage > 0 ? Colors.black : Colors.grey,
                        ),
                      ),
                      // 中间计数器
                      Text(
                        '${currentPage + 1}/$totalPage',
                        style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
                      ),
                      // 右箭头按钮
                      IconButton(
                        onPressed: currentPage < totalPage - 1 ? () {
                          // 切换到下一页
                          controller.pageViewController.nextPage(
                            duration: const Duration(milliseconds: 300), 
                            curve: Curves.easeInOut
                          );
                          // 同步Modular路由
                          Modular.to.navigate('/createaccount/pageStep${currentPage + 2}');
                        } : null,
                        icon: Icon(
                          Icons.arrow_forward_ios,
                          color: currentPage < totalPage - 1 ? Colors.black : Colors.grey,
                        ),
                      ),
                    ],
                  ),
                );
              },
            ));
      }
}

如果需要允许用户手动滑动PageView切换页面,删掉physics: const NeverScrollableScrollPhysics()即可,AnimatedBuilder会自动监听滑动事件更新计数器和按钮状态,你也可以根据需求调整底部容器的padding、按钮样式、计数器文字样式来匹配设计稿。

内容的提问来源于stack exchange,提问作者Ronaldo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 13:06:05