Flutter CustomScrollView中的Flatter SliverPersistentHeader在到达底部小部件之前到达maxScrollExtend

Flutter CustomScrollView中的Flatter SliverPersistentHeader在到达底部小部件之前到达maxScrollExtend,flutter,customscrollview,Flutter,Customscrollview,我正在尝试实现垂直滚动的堆叠卡片列表视图。当我使用stack时,我无法平滑地滚动它们。所以我决定使用CustomScrollView和SliverPersistentHeader。不幸的是,SliverPersistentHeader列表在滚动时无法触及底部小部件。谁能救我一天 class StackedList extends StatefulWidget { @override _StackedListState createState() => _StackedListSta

我正在尝试实现垂直滚动的堆叠卡片列表视图。当我使用stack时,我无法平滑地滚动它们。所以我决定使用CustomScrollView和SliverPersistentHeader。不幸的是,SliverPersistentHeader列表在滚动时无法触及底部小部件。谁能救我一天

class StackedList extends StatefulWidget {
  @override
  _StackedListState createState() => _StackedListState();
}

class _StackedListState extends State<StackedList> {
  final List<Color> colors = Colors.primaries;
  static const _minHeight = 24.0;
  static const _maxHeight = 80.0;
  @override
  Widget build(BuildContext context) {
    List<Color> _colors = List();
    _colors.addAll(colors);

    return CustomScrollView(
      physics: ClampingScrollPhysics(),
      shrinkWrap: false,
      slivers: <Widget>[
        ..._colors
            .map(
              (color) => StackedListChild(
                minHeight: _minHeight,
                maxHeight: _maxHeight,
                floating: false,
                pinned: true,
                child: getCard(
                  cardId: _colors.indexOf(color).toString(),
                  color: color,
                ),
              ),
            )
            .toList(),
      ],
    );
  }


}

class StackedListChild extends StatelessWidget {
  final double minHeight;
  final double maxHeight;
  final bool pinned;
  final bool floating;
  final Widget child;

  SliverPersistentHeaderDelegate get _delegate => _StackedListDelegate(
      minHeight: minHeight, maxHeight: maxHeight, child: child);

  const StackedListChild({
    Key key,
    @required this.minHeight,
    @required this.maxHeight,
    @required this.child,
    this.pinned = false,
    this.floating = false,
  })  : assert(child != null),
        assert(minHeight != null),
        assert(maxHeight != null),
        assert(pinned != null),
        assert(floating != null),
        super(key: key);

  @override
  Widget build(BuildContext context) => SliverPersistentHeader(
      key: key, pinned: pinned, floating: floating, delegate: _delegate);
}

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

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

  @override
  double get minExtent => minHeight;

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

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

  @override
  bool shouldRebuild(_StackedListDelegate oldDelegate) {
    return maxHeight != oldDelegate.maxHeight ||
        minHeight != oldDelegate.minHeight ||
        child != oldDelegate.child;
  }
}
class StackedList扩展了StatefulWidget{
@凌驾
_StackedListState createState()=>\u StackedListState();
}
类_StackedListState扩展状态{
最终列表颜色=colors.primaries;
静态常数最小高度=24.0;
静态常数最大高度=80.0;
@凌驾
小部件构建(构建上下文){
列表_colors=List();
_颜色。添加所有(颜色);
返回自定义滚动视图(
物理:ClampingScrollPhysics(),
收缩膜:假,
条子:[
颜色
.地图(
(颜色)=>StackedListChild(
最小高度:_最小高度,
maxHeight:_maxHeight,
浮动:假,
对,,
孩子:getCard(
cardId:_colors.indexOf(color.toString(),
颜色:颜色,
),
),
)
.toList(),
],
);
}
}
类StackedListChild扩展了无状态小部件{
最终双倍高度;
最终双倍最大高度;
最后一步;
最终布尔浮动;
最后一个孩子;
SliverPersistentHeaderDelegate获取_delegate=>_StackedListDelegate(
最小高度:最小高度,最大高度:最大高度,子级:子级);
常量StackedListChild({
关键点,
@需要此参数。最小高度,
@需要此.maxHeight,
@需要这个孩子,
this.pinted=false,
this.floating=false,
}):assert(child!=null),
断言(最小高度!=null),
断言(maxHeight!=null),
断言(pinted!=null),
断言(浮动!=null),
超级(键:键);
@凌驾
小部件构建(BuildContext上下文)=>SliverPersistentHeader(
关键点:关键点,固定:固定,浮动:浮动,委托:\委托);
}
类_StackedListDelegate扩展SliverPersistentHeaderDelegate{
最终双倍高度;
最终双倍最大高度;
最后一个孩子;
_StackedListDelegate({
@需要此参数。最小高度,
@需要此.maxHeight,
@需要这个孩子,
});
@凌驾
double get minExtent=>minHeight;
@凌驾
double-get-maxExtent=>math.max(maxHeight,minHeight);
@凌驾
小部件构建(
BuildContext上下文、双收缩偏移、布尔重叠内容){
返回新的SizedBox.expand(子项:子项);
}
@凌驾
bool应重新生成(\u StackedListDelegate oldDelegate){
返回maxHeight!=oldDelegate.maxHeight||
最小高度!=oldDelegate.minHeight||
child!=oldDelegate.child;
}
}

在列表末尾添加一个小片段视图,该视图的高度足以留出足够的空间滚动小片段PersistentHeader直到最后一个

slivers: <Widget>[
    ..._colors
        .map(
          (color) => StackedListChild(
            minHeight: _minHeight,
            maxHeight: _maxHeight,
            floating: false,
            pinned: true,
            child: getCard(
              cardId: _colors.indexOf(color).toString(),
              color: color,
            ),
          ),
        )
        .toList(),


   ///extra bottom padding sliver
   SliverToBoxAdapter(
        child: Container(
         height: MediaQuery.of(context).size.height,
         alignment:Alignment.center,

          ))
  ],
条子:[
颜色
.地图(
(颜色)=>StackedListChild(
最小高度:_最小高度,
maxHeight:_maxHeight,
浮动:假,
对,,
孩子:getCard(
cardId:_colors.indexOf(color.toString(),
颜色:颜色,
),
),
)
.toList(),
///额外的底部填充棉条
滑动双轴适配器(
子:容器(
高度:MediaQuery.of(context).size.height,
对齐:对齐.center,
))
],
观看现场演示