Kavantix / sliver_tools

A set of useful sliver tools that are missing from the flutter framework
MIT License
652 stars 64 forks source link

MultiSliver fails in a shrinkwrapped, unconstrained CustomScrollView #95

Open HeinrichJanzing opened 3 months ago

HeinrichJanzing commented 3 months ago

MultiSliver calculates an invalid SliverGeometry when the incoming SliverConstraints.remainingCacheExtent is infinity. Infinity should be accepted: according to the docs, remainingPaintExtent can be infinity and remainingCacheExtent is always >= remainingPaintExtent. One situation in which this occurs is a shrinkwrapped CustomScrollView unconstrained on its main axis.

Specifically, RenderMultiSliver sets its SliverGeometry.cacheExtent to NaN, by subtracting infinity from infinity in this calculation in RenderMultiSliver._layoutChildSequence. This causes a series of assertion failures and incomplete rendering.

I suspect the code should instead accumulate the cacheExtent of the children to determine its own cacheExtent, as it does for the paintExtent already.

This app reproduces the problem for me, using sliver_tools 0.2.12:

import 'package:flutter/material.dart';
import 'package:sliver_tools/sliver_tools.dart';

void main() {
  runApp(const MainApp());
}

class MainApp extends StatelessWidget {
  const MainApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: UnconstrainedBox(
            constrainedAxis: Axis.horizontal,
            child: CustomScrollView(shrinkWrap: true, slivers: [
              MultiSliver(children: const [SizedBox(height: 100)])
            ])));
  }
}
Kavantix commented 3 months ago

Thanks for creating the issue and already doing some research for me! I’ll see if I can make some time in the near future to take a closer look. A PR would also be welcome