Flutter Smooth Page Indicator自定义PaintStyle:激活点填充非激活点带边框
解决SmoothPageIndicator激活点填充、非激活点空心带边框的需求
原生的SmoothPageIndicator并没有直接提供配置项让你分别给激活点和非激活点设置不同的PaintingStyle,但可以通过自定义Effect来实现你要的效果,完全满足无障碍访问的需求。
实现步骤
- 自定义一个继承自现有Effect的类(比如基于
ExpandingDotsEffect改造),重写draw方法,分别处理激活点和非激活点的绘制逻辑:
import 'package:flutter/material.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart'; class CustomDotEffect extends ExpandingDotsEffect { final Color inactiveBorderColor; final double inactiveBorderWidth; const CustomDotEffect({ super.activeDotColor = Colors.blue, super.dotColor = Colors.transparent, // 非激活点内部设为透明 super.dotHeight = 16, super.dotWidth = 16, super.spacing = 8, this.inactiveBorderColor = Colors.grey, this.inactiveBorderWidth = 2, }); @override void draw( Canvas canvas, PageController controller, int count, double dotAnim, Paint paint, ) { for (var i = 0; i < count; i++) { final currentPage = controller.page ?? 0; final isActive = i == currentPage.round(); final x = i * (dotWidth + spacing) + dotWidth / 2; final y = dotHeight / 2; if (isActive) { // 激活点:填充样式 paint.style = PaintingStyle.fill; paint.color = activeDotColor; canvas.drawCircle(Offset(x, y), dotWidth / 2, paint); } else { // 非激活点:空心带边框 paint.style = PaintingStyle.stroke; paint.color = inactiveBorderColor; paint.strokeWidth = inactiveBorderWidth; canvas.drawCircle(Offset(x, y), dotWidth / 2, paint); } } } }
- 在
SmoothPageIndicator中使用这个自定义Effect:
SmoothPageIndicator( controller: _pageController, // 你的PageController实例 count: 3, // 页面总数 effect: CustomDotEffect( activeDotColor: const Color(0xFF007AFF), // 激活点填充色 inactiveBorderColor: const Color(0xFF8E8E93), // 非激活点边框色 inactiveBorderWidth: 2, dotWidth: 16, dotHeight: 16, spacing: 12, ), )
无障碍优化提示
为了符合无障碍访问标准,建议:
- 确保激活点与非激活点的颜色对比度至少达到4.5:1
- 可配合
Semantics组件给指示器添加语义标签,提升屏幕阅读器的识别体验
内容的提问来源于stack exchange,提问作者Jane
相关产品推荐
相关产品推荐

