FlexibleSpaceBar 解析之background

文章目录

        • FlexibleSpaceBar
        • Code
        • background 高度
        • 判断是否折叠 constraints.biggest.height

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(),
       ),
     );
   }
 )

你可能感兴趣的:(flutter,flutter)