FlexibleSpaceBar 解析之background

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: FlexibleSpaceBar 解析之background
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});

  @override
  State<FlexibleSpaceBarBackground> createState() =>
      _FlexibleSpaceBarBackgroundState();
}

class _FlexibleSpaceBarBackgroundState
    extends State<FlexibleSpaceBarBackground> {
  final heightKey = GlobalKey();

  @override
  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}');
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Container(
          key: heightKey,
          child: widget.child,
        ),
        const Spacer()
      ],
    );
  }
}
class HeaderDetail extends StatelessWidget {
  
  const HeaderDetail(
      {super.key});

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

相关文章
|
25天前
|
前端开发
content-box和border-box是什么?
content-box和border-box是什么?
57 0
|
12月前
|
JavaScript
background-color设置为透明的方法
background-color设置为透明的方法
159 0
|
前端开发
opacity和background的rgba区别
opacity和background的rgba区别
|
前端开发
每日一学—CSS overflow与text-overflow与white-space属性
CSS overflow 属性可以控制内容溢出元素框时在对应的元素区间内添加滚动条。text-overflow 属性指定当文本溢出包含它的元素时,应该如何显示。可以设置溢出后,文本被剪切、显示省略号 (...) 或显示自定义字符串(不是所有浏览器都支持)。white-space属性指定元素内的空白怎样处理。
284 0
每日一学—CSS overflow与text-overflow与white-space属性
|
前端开发
CSS - 行内元素的 padding、margin、width、height、line-height 是否无效?
CSS - 行内元素的 padding、margin、width、height、line-height 是否无效?
498 0
CSS - 行内元素的 padding、margin、width、height、line-height 是否无效?
|
前端开发
CSS中使用background:url(地址)显示,但是background-image:url(地址)不显示的原因
CSS中使用background:url(地址)显示,但是background-image:url(地址)不显示的原因
770 0
|
Web App开发 前端开发 Android开发