Pageview Builder滑动时居中Widget边框设为激活色实现咨询
实现PageView滑动时居中Widget激活边框的方案
核心逻辑
通过监听PageView的滚动偏移,实时计算当前居中位置对应的item索引,动态为对应Widget切换激活色边框,非居中Widget保持默认样式,滑动过程中实时更新状态确保边框颜色始终跟随居中项变化。
具体实现步骤
- 初始化核心变量:用
PageController控制PageView,同时定义_currentIndex记录当前居中item的索引;若PageView设置了viewportFraction(item宽度小于屏幕宽度),需提前声明该参数用于后续计算。 - 监听滚动事件:在
initState中为PageController添加滚动监听,通过controller.page获取滚动偏移对应的页面位置,取整后得到当前最接近居中的item索引,索引变化时调用setState更新状态。 - 动态设置边框样式:在
PageView.builder的itemBuilder中,对比当前item索引与_currentIndex,相等时使用激活色边框,否则使用默认边框(比如透明色)。
完整代码示例
import 'package:flutter/material.dart'; class CenteredActiveBorderPageView extends StatefulWidget { const CenteredActiveBorderPageView({super.key}); @override State<CenteredActiveBorderPageView> createState() => _CenteredActiveBorderPageViewState(); } class _CenteredActiveBorderPageViewState extends State<CenteredActiveBorderPageView> { late PageController _pageController; int _currentIndex = 0; // 自定义item占屏幕宽度的比例,按需调整 final double viewportFraction = 0.8; @override void initState() { super.initState(); _pageController = PageController(viewportFraction: viewportFraction) ..addListener(_onPageScroll); } void _onPageScroll() { final page = _pageController.page ?? 0; final currentIndex = page.round(); if (currentIndex != _currentIndex) { setState(() { _currentIndex = currentIndex; }); } } @override void dispose() { _pageController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: SizedBox( height: 200, child: PageView.builder( controller: _pageController, itemCount: 5, itemBuilder: (context, index) { final isActive = index == _currentIndex; return Container( margin: const EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( color: index % 2 == 0 ? Colors.grey[300] : Colors.purple[200], border: Border.all( color: isActive ? Colors.blue : Colors.transparent, width: 3, ), borderRadius: BorderRadius.circular(8), ), child: Center( child: Text( index == 0 ? "Silver Widget" : "Purple Widget", style: const TextStyle(fontSize: 18), ), ), ); }, ), ), ), ); } }
补充说明
- 若PageView为全屏宽度(
viewportFraction=1.0),直接使用_pageController.page?.round()即可准确获取当前页面索引; - 如需更精确的居中触发逻辑(比如item中心进入屏幕中心区域才激活),可通过计算item位置与屏幕中心的偏移量来判断,替代简单的取整方式;
- 滚动过程中监听事件会持续触发,
setState会实时更新UI,确保边框颜色始终跟随居中项变化。
内容的提问来源于stack exchange,提问作者Ajith S
相关产品推荐
相关产品推荐

