Flutter Sliver 标头固定在顶部和底部

问题描述 投票:0回答:1

我正在开发一个 Flutter 项目,想要实现一个带有固定标题的 CustomScrollView。具体来说,我希望每个标题仅在完全滚动过去后才粘在屏幕顶部。在那之前,它应该保留在它所属部分的底部。

这种行为在 Flutter 中可能吗?如果是这样,实现这一目标的最佳方法是什么?

在下面的屏幕截图中,我们当前正在滚动浏览“标题 2”部分,我希望将“标题 3”和“标题 4”固定在底部。

CustomScrollView screenshot

flutter flutter-sliver
1个回答
0
投票

是的,这种行为是完全可能的,但需要一些定制。

SliverAppBar 默认只能将 header 固定在顶部,所以要实现这种“上下固定”的效果,需要结合使用 CustomScrollViewSliverPercientHeader 以及一些自定义逻辑来控制标头的行为方式。

以下是如何实现此目标的基本示例:

class MyPinnedHeaders extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
 return Scaffold(
  body: CustomScrollView(
    slivers: [
      // Header 1 - Pinned to the top
      SliverPersistentHeader(
        pinned: true,
        delegate: _HeaderDelegate(
          minHeight: 50,
          maxHeight: 150,
          child: Container(
            color: Colors.red,
            child: Center(child: Text('Header 1')),
          ),
        ),
      ),

      // Content under Header 1
      SliverToBoxAdapter(
        child: Container(height: 200, color: Colors.green, child: Text('Item 3')),
      ),

      // Header 2 - Pinned to the top
      SliverPersistentHeader(
        pinned: true,
        delegate: _HeaderDelegate(
          minHeight: 50,
          maxHeight: 150,
          child: Container(
            color: Colors.blue,
            child: Center(child: Text('Header 2')),
          ),
        ),
      ),

      // Content under Header 2
      SliverToBoxAdapter(
        child: Container(height: 200, color: Colors.green, child: Text('Item 4')),
      ),
    ],
   ),
  );
 }
}

class _HeaderDelegate extends SliverPersistentHeaderDelegate {
 final double minHeight;
 final double maxHeight;
 final Widget child;

_HeaderDelegate({
 required this.minHeight,
 required this.maxHeight,
 required this.child,
});

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

 @override
 double get maxExtent => maxHeight;

 @override
 double get minExtent => minHeight;

 @override
 bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate){
  return true;
 }
}

这将使您的标题在您滚动经过它们时固定在顶部。如果您希望标题也固定在部分的底部,您可以自定义 SliverPercientHeaderDelegate 通过控制标题的放置方式来实现该行为。

image

© www.soinside.com 2019 - 2024. All rights reserved.