如何让FlexibleSpaceBar的title在SliverAppBar收缩时替换其原有title
SliverAppBar滚动收缩隐藏原有标题解决方案
问题原因
直接为SliverAppBar设置固定title属性时,该标题默认常驻显示,不会跟随滚动状态变化透明度,因此会和上浮的FlexibleSpaceBar标题出现重叠。
实现思路
通过滚动控制器监听NestedScrollView的滚动偏移,动态计算原有HOME标题的透明度:SliverAppBar完全展开时透明度为1,完全收缩时透明度为0,滚动过程中透明度线性变化,实现自然淡出效果,同时保留FlexibleSpaceBar原有title的浮动逻辑。
完整修改后代码
import 'package:flutter/material.dart'; class _MyHomePageState extends State<MyHomePage> { // 新增滚动控制器与透明度状态变量 late ScrollController _scrollController; double _homeTitleOpacity = 1.0; @override void initState() { super.initState(); _scrollController = ScrollController(); // 监听滚动事件动态计算透明度 _scrollController.addListener(() { double offset = _scrollController.offset; // SliverAppBar可滚动的最大偏移:展开高度 - 系统默认工具栏高度 double maxScrollOffset = 120 - kToolbarHeight; if (offset <= 0) { _homeTitleOpacity = 1.0; } else if (offset >= maxScrollOffset) { _homeTitleOpacity = 0.0; } else { _homeTitleOpacity = 1 - (offset / maxScrollOffset); } setState(() {}); }); } @override void dispose() { // 销毁滚动控制器避免内存泄漏 _scrollController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: DefaultTabController( length: 3, // 为NestedScrollView绑定滚动控制器 child: NestedScrollView( controller: _scrollController, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return <Widget>[ SliverAppBar( elevation: 0, // 原有标题用Opacity组件包裹,动态设置透明度 title: Opacity( opacity: _homeTitleOpacity, child: const Text('HOME'), ), backgroundColor: Colors.green, pinned: true, stretchTriggerOffset: 10, onStretchTrigger: () async{ print('hello'); return; }, automaticallyImplyLeading: false, actions: const [ Padding( padding: EdgeInsets.only(right: 30), child: Icon(Icons.ac_unit), ) ], expandedHeight: 120, flexibleSpace: const FlexibleSpaceBar( title: Text('Charity',style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold, color: Colors.white),), stretchModes: [ StretchMode.fadeTitle ], ), ), ]; }, body: const Text("this is good"), ), ), ); } }
内容的提问来源于stack exchange,提问作者Thanoss
相关产品推荐
相关产品推荐

