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

Flutter Onboarding Slider组件最后一页指示器不显示问题求助

问题:flutter_onboarding_slider隐藏浮动按钮后底部指示器消失的解决办法

使用flutter_onboarding_slider:1.0.9开发应用引导页时,设置hasFloatingButton: false后,最后一页的底部指示器无法显示,相关代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_onboarding_slider/flutter_onboarding_slider.dart';

class OnBoradingPackage extends StatefulWidget {
  const OnBoradingPackage({super.key});

  @override
  State<OnBoradingPackage> createState() => _OnBoradingPackageState();
}

class _OnBoradingPackageState extends State<OnBoradingPackage> {
  final List<Widget> bgWidgets = const [
    PageWidget(color: Colors.red),
    PageWidget(color: Colors.green),
    PageWidget(color: Colors.yellow),
    PageWidget(color: Colors.blue),
  ];

  final List<String> imgList = [
    'assets/1.jpg',
    'assets/2.jpg',
    'assets/3.jpg',
    'assets/4.jpg',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Package'),
      ),
      body: SafeArea(
        top: true,
        bottom: false,
        child: OnBoardingSlider(
          totalPage: 4,
          headerBackgroundColor: Colors.transparent,
          background: bgWidgets,
          speed: 0,
          pageBodies: [for (var img in imgList) Image.asset(img)],
          hasFloatingButton: false,
        ),
      ),
    );
  }
}

class PageWidget extends StatelessWidget {
  const PageWidget({super.key, required this.color});

  final Color color;

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(color: color),
    );
  }
}

解决办法

方法1:自定义底部指示器(推荐)

组件内部逻辑在隐藏浮动按钮时会移除指示器布局,最可靠的方式是自行添加独立指示器,通过PageController同步页面状态:

修改后的代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_onboarding_slider/flutter_onboarding_slider.dart';

class OnBoradingPackage extends StatefulWidget {
  const OnBoradingPackage({super.key});

  @override
  State<OnBoradingPackage> createState() => _OnBoradingPackageState();
}

class _OnBoradingPackageState extends State<OnBoradingPackage> {
  final List<Widget> bgWidgets = const [
    PageWidget(color: Colors.red),
    PageWidget(color: Colors.green),
    PageWidget(color: Colors.yellow),
    PageWidget(color: Colors.blue),
  ];

  final List<String> imgList = [
    'assets/1.jpg',
    'assets/2.jpg',
    'assets/3.jpg',
    'assets/4.jpg',
  ];
  
  final PageController _pageController = PageController();
  int _currentPage = 0;

  @override
  void initState() {
    super.initState();
    _pageController.addListener(() {
      setState(() {
        _currentPage = _pageController.page?.round() ?? 0;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Package'),
      ),
      body: SafeArea(
        top: true,
        bottom: false,
        child: Stack(
          children: [
            OnBoardingSlider(
              totalPage: 4,
              headerBackgroundColor: Colors.transparent,
              background: bgWidgets,
              speed: 0,
              pageBodies: [for (var img in imgList) Image.asset(img)],
              hasFloatingButton: false,
              pageController: _pageController,
            ),
            Positioned(
              bottom: 30,
              left: 0,
              right: 0,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: List.generate(4, (index) {
                  return Container(
                    width: 8,
                    height: 8,
                    margin: const EdgeInsets.symmetric(horizontal: 4),
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      color: _currentPage == index ? Colors.white : Colors.white54,
                    ),
                  );
                }),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class PageWidget extends StatelessWidget {
  const PageWidget({super.key, required this.color});

  final Color color;

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(color: color),
    );
  }
}

方法2:临时绕过组件bug

如果不想自定义指示器,可以设置完全透明的浮动按钮,让组件保留指示器布局:

修改OnBoardingSlider参数:

OnBoardingSlider(
  totalPage: 4,
  headerBackgroundColor: Colors.transparent,
  background: bgWidgets,
  speed: 0,
  pageBodies: [for (var img in imgList) Image.asset(img)],
  hasFloatingButton: true,
  floatingButton: Opacity(
    opacity: 0,
    child: ElevatedButton(
      onPressed: () {},
      child: const Text(''),
    ),
  ),
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:40:28