【Flutter】头部导航条变换

描述:滑动列表时顶部导航栏由高边窄颜色变换

布局:列表顶部是张图片,下面是列表,滚动列表时头部图片移动上去,上面的导航条慢慢出来,导航栏上的图标颜色变换

CustomScrollView(
              slivers: [
                SliverPersistentHeader(
                  delegate: SliverHeaderDelegate(
                    minHeight: MediaQuery.of(context).padding.top + 44,
                    maxHeight: 211,
                    onBind: (context, shrinkOffset, overlapsContent) {
                      final minExtent = MediaQuery.of(context).padding.top + 44;
                      final maxExtent = 211.0;
                      final toolbarOpacity = 1 - ((maxExtent - shrinkOffset - minExtent) / minExtent).clamp(0.0, 1.0);
                      final opacity = Interval(0.25, 1.0, curve: Curves.fastOutSlowIn).transform(toolbarOpacity);
                      final iconColor = ColorTween(begin: Colors.black, end: Colors.white).transform(1 - opacity);
                      return FlexibleSpaceBar.createSettings(
                        minExtent: minExtent,
                        maxExtent: maxExtent,
                        currentExtent: max(minExtent, maxExtent - shrinkOffset),
                        toolbarOpacity: toolbarOpacity,
                        child: GestureDetector(
                          onTap: (){
                            print('视频播放界面');
                          },
                          child: Stack(
                            children: [
                              ImageWidget(
                                width: MediaQuery.of(context).size.width,
                                height: 211,
                                imageStr: state.data.coverImage,
                              ),
                              Positioned.fromRect(
                                child: Image.asset('assets/ic_play.png'),
                                rect: Rect.fromLTWH(0, 0, MediaQuery.of(context).size.width, 211),
                              ),

                              Container(
                                decoration: BoxDecoration(
                                  color: Colors.white.withOpacity(opacity),
                                  boxShadow: [
                                    BoxShadow(
                                      color: Color(0x33999999).withOpacity(opacity.truncate().toDouble()),
                                      blurRadius: 5,
                                    )
                                  ],
                                ),
                                child: SafeArea(
                                  bottom: false,
                                  child: Container(
                                    height: 44,
                                    child: Row(
                                      children: [
                                        Expanded(
                                          child: Container(
                                            alignment: Alignment.centerLeft,
                                            child: IconButton(
                                              icon: const Icon(Icons.arrow_back_ios, size: 20),
                                              color: iconColor,
                                              onPressed: () {
                                                Navigator.maybePop(context);
                                              },
                                            ),
                                          )),
                                        Expanded(
                                          child: Container(
                                            alignment: Alignment.center,
                                            child: Text(
                                              '直播详情',
                                              style: TextStyle(
                                                fontSize: 18,
                                                color: res.Colors.majorTextColor.withOpacity(opacity),
                                              ),
                                            ),
                                          )),
                                        Expanded(
                                          child: Container(),
                                        ),
                                      ],
                                    ),
                                  ),
                                ),
                              ),

                            ],
                          ),
                        )
                      );
                    },
                  ),
                  floating: false,
                  pinned: true,
                ),
                SliverList(
                  delegate: SliverChildListDelegate([
                    _buildTimeWidget(state),
                    _buildliveDataWidget(state),
                    SizedBox(height: 10,),
                    _buildSalesDataWidget(state),
                  ]),
                )
              ],
            )

class SliverHeaderDelegate extends SliverPersistentHeaderDelegate {
  SliverHeaderDelegate({
    @required this.minHeight,
    @required this.maxHeight,
    @required this.onBind,
  });

  final double minHeight;
  final double maxHeight;
  final BuildCallback onBind;
  Widget _child;

  @override
  double get minExtent => minHeight;

  @override
  double get maxExtent => max(maxHeight, minHeight);

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    _child = onBind(context, shrinkOffset, overlapsContent);
    return SizedBox.expand(child: _child);
  }

  @override
  bool shouldRebuild(SliverHeaderDelegate oldDelegate) {
    return maxHeight != oldDelegate.maxHeight || minHeight != oldDelegate.minHeight || _child != oldDelegate._child;
  }
}

typedef BuildCallback = Widget Function(BuildContext context, double shrinkOffset, bool overlapsContent);

【Flutter】头部导航条变换_第1张图片

你可能感兴趣的:(Flutter)