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

Flutter自定义PageView求助:实现3页面带透明度与缩放效果

自定义带缩放&透明度效果的Flutter PageView实现方案

直接用原生PageView结合Transform、Opacity和PageController就能实现需求,不需要依赖第三方包,核心是利用页面偏移量动态计算每个页面的变换参数:

核心实现步骤

  1. 配置PageController:设置viewportFraction小于1,让页面宽度小于屏幕,从而显示左右相邻页面
  2. 监听页面偏移:通过AnimatedBuilder监听PageController的动画状态,实时计算每个页面的缩放和透明度值
  3. 应用变换效果:将计算出的参数应用到Transform.scale和Opacity组件上

完整代码示例

import 'package:flutter/material.dart';

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

  @override
  State<CustomPageView> createState() => _CustomPageViewState();
}

class _CustomPageViewState extends State<CustomPageView> {
  final PageController _pageController = PageController(viewportFraction: 0.8);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: SizedBox(
          height: MediaQuery.of(context).size.height * 0.7,
          child: PageView.builder(
            controller: _pageController,
            itemCount: 5,
            itemBuilder: (context, index) {
              return AnimatedBuilder(
                animation: _pageController,
                builder: (context, child) {
                  double pageValue = 0.0;
                  if (_pageController.position.haveDimensions) {
                    pageValue = _pageController.page! - index;
                  }
                  // 计算缩放值:当前页面为1,左右页面随偏移量缩小,最小0.7
                  final double scale = (1 - (pageValue.abs() * 0.3)).clamp(0.7, 1.0);
                  // 计算透明度:和缩放关联,也可单独调整系数
                  final double opacity = scale;

                  return Transform.scale(
                    scale: scale,
                    child: Opacity(
                      opacity: opacity,
                      child: child,
                    ),
                  );
                },
                child: Container(
                  margin: const EdgeInsets.symmetric(horizontal: 8),
                  decoration: BoxDecoration(
                    color: Colors.primaries[index % Colors.primaries.length],
                    borderRadius: BorderRadius.circular(16),
                  ),
                  child: Center(
                    child: Text(
                      "页面 $index",
                      style: const TextStyle(fontSize: 24, color: Colors.white),
                    ),
                  ),
                ),
              );
            },
          ),
        ),
      ),
    );
  }
}

自定义调整建议

  • 调整viewportFraction(比如0.75、0.85)可以改变页面显示的宽度比例
  • 修改缩放系数0.3和透明度逻辑,能匹配目标效果图的视觉强度
  • 如果需要左右页面效果不对称,可以拆分pageValue的正负值分别计算缩放和透明度:
    double scale = 1.0;
    double opacity = 1.0;
    if (pageValue > 0) {
      // 右侧页面的缩放/透明度规则
      scale = 1 - pageValue * 0.25;
      opacity = 1 - pageValue * 0.4;
    } else {
      // 左侧页面的缩放/透明度规则
      scale = 1 + pageValue * 0.25;
      opacity = 1 + pageValue * 0.4;
    }
    scale = scale.clamp(0.7, 1.0);
    opacity = opacity.clamp(0.6, 1.0);
    
  • 保持pageSnapping: true(默认开启)可以实现页面滑动后的吸附效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 07:07:27