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

如何实现Flutter AppBar随滚动切换颜色与标题渐变效果?

Flutter 滚动渐变 AppBar 实现方案

无状态组件(Stateless Widget)无法维护滚动状态,必须用有状态组件(Stateful Widget)实现这个需求。以下是完整实现代码,包含滚动时AppBar从透明到带色、标题渐显的效果:

import 'package:flutter/material.dart';

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

  @override
  State<ScrollGradientAppBar> createState() => _ScrollGradientAppBarState();
}

class _ScrollGradientAppBarState extends State<ScrollGradientAppBar> {
  final ScrollController _scrollController = ScrollController();
  double _scrollOffset = 0.0;
  // 过渡完成的临界滚动偏移量,可按需调整
  final double _maxOffset = 200.0;

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(_onScroll);
  }

  void _onScroll() {
    setState(() {
      // 限制偏移量不超过临界值
      _scrollOffset = _scrollController.offset.clamp(0.0, _maxOffset);
    });
  }

  @override
  void dispose() {
    _scrollController.removeListener(_onScroll);
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // 计算滚动进度(0到1之间)
    final double progress = _scrollOffset / _maxOffset;
    final double opacity = progress;

    return Scaffold(
      // 自定义AppBar,保持标准AppBar高度
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(kToolbarHeight),
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 16),
          color: Colors.blue.withOpacity(opacity),
          child: Row(
            children: [
              // 左侧图标按钮,始终显示
              IconButton(
                icon: const Icon(Icons.menu, color: Colors.white),
                onPressed: () {},
              ),
              const Spacer(),
              // 标题随滚动进度渐显
              Opacity(
                opacity: opacity,
                child: const Text(
                  '首页',
                  style: TextStyle(color: Colors.white, fontSize: 18),
                ),
              ),
              const Spacer(),
              // 右侧图标按钮,始终显示
              IconButton(
                icon: const Icon(Icons.search, color: Colors.white),
                onPressed: () {},
              ),
              IconButton(
                icon: const Icon(Icons.notifications, color: Colors.white),
                onPressed: () {},
              ),
            ],
          ),
        ),
      ),
      body: ListView.builder(
        controller: _scrollController,
        itemCount: 50,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('列表项 $index'),
          );
        },
      ),
    );
  }
}

关键实现说明

  • 滚动监听:通过ScrollController监听滚动偏移量,在_onScroll中更新状态,限制偏移量不超过设定的临界值_maxOffset
  • 渐变计算:用progress = _scrollOffset / _maxOffset得到0-1的进度值,以此控制AppBar背景色透明度和标题显示透明度
  • 自定义AppBar:用PreferredSizeWidget包裹Container,保证和标准AppBar高度一致,图标按钮始终可见,标题随进度渐显
  • 资源释放:在dispose中移除监听并销毁ScrollController,避免内存泄漏

调整过渡速度或临界偏移量,直接修改_maxOffset即可;背景色也可替换为你需要的颜色。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 05:32:47