FlexibleSpaceBar
Stack
Height
background
Code
///_FlexibleSpaceBarState
///返回了一个ClipRect
ClipRect(child: Stack(children: children))
///background的高度
children.add(Positioned(
top: topPadding,
left: 0.0,
right: 0.0,
height: height,
child: _FlexibleSpaceHeaderOpacity(
// IOS is relying on this semantics node to correctly traverse
// through the app bar when it is collapsed.
alwaysIncludeSemantics: true,
opacity: opacity,
child: widget.background,
),
));
///获取高度
double height = settings.maxExtent;
// StretchMode.zoomBackground
if (widget.stretchModes.contains(StretchMode.zoomBackground) &&
constraints.maxHeight > height) {
height = constraints.maxHeight;
}
///_SliverAppBarDelegate
double get maxExtent => math.max(topPadding + (expandedHeight ?? (toolbarHeight ?? kToolbarHeight) + _bottomHeight), minExtent);
background 高度
SliverAppBar的expandedHeight会强制FlexibleSpaceBar的background的高度一致,如果直接获取子组件的高度就会得到expandedHeight的值,
如果想要获取到真实内容的高度,需要套一个Column或者其他Widget,然后通过Key获取高度,代码如下
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
class FlexibleSpaceBarBackground extends StatefulWidget {
final Function(double) setHeight;
final Widget child;
const FlexibleSpaceBarBackground(
{super.key, required this.setHeight, required this.child});
State<FlexibleSpaceBarBackground> createState() =>
_FlexibleSpaceBarBackgroundState();
}
class _FlexibleSpaceBarBackgroundState
extends State<FlexibleSpaceBarBackground> {
final heightKey = GlobalKey();
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
final heightRO = heightKey.currentContext?.findRenderObject();
if (heightRO != null && heightRO is RenderBox) {
widget.setHeight(heightRO.size.height);
print('heightRO.size.height=${heightRO.size.height}');
}
});
}
Widget build(BuildContext context) {
return Column(
children: [
Container(
key: heightKey,
child: widget.child,
),
const Spacer()
],
);
}
}
class HeaderDetail extends StatelessWidget {
const HeaderDetail(
{super.key});
Widget build(BuildContext context) {
return Column(
children: [
Text('================'),
const Gap.v(10),
Text('================'),
const Gap.v(10),
],
);
}
}
SliverAppBar(
///此属性为折叠后的高度,默认为toolbarHeight
///"collapsedHeight"参数必须大于或等于[toolbarHeight]
collapsedHeight: 0,
toolbarHeight: 0,
backgroundColor: Colors.transparent,
pinned: true,
expandedHeight: height.value,
flexibleSpace: FlexibleSpaceBar(
background: FlexibleSpaceBarBackground(
doResult: setHeight,
child:HeaderDetail(),
),
),
bottom: PreferredSize(
preferredSize: Size.fromHeight(42),
child: Container(
color: Colors.white,
child: TabBar(
tabs: items.value,
controller: tabC,
unselectedLabelColor: Colors.grey,
indicator:
context.extensions.underlineTabIndicator,
),
),
),
)
///设置高度
final setHeight = useCallback((double height_) {
height.value = height_ + 42;
}, []);
判断是否折叠 constraints.biggest.height
LayoutBuilder(
builder: (context,constraints) {
///此属性是appbar的高度,如果等于42说明已折叠 因为bottom的高度是42
constraints.biggest.height.log();
return FlexibleSpaceBar(
background: FlexibleSpaceBarBackground(
setHeight: setHeight,
child: HeaderProductDetail(),
),
);
}
)