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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:12:12