Repository: flutter
Issue: Build many nested lists of slivers lazily
Labels: framework,f: scrolling,would be a good package,c: proposal,P3,team-framework,triaged-framework

### Use case

The use case is a view that displays chat messages and their history like popular messaging Apps do it. All messages of one day should have a sticky date header. There can be many messages for each day and also many days in the chat history (multiple years e.g.). The list should still scroll smoothly, and all messages and days should be built lazily.

This is not possible with the stock flutter widgets available, today. There are workarounds, which have severe disadvantages, though:

**Workaround 1:**
Use a `CustomScrollView` with a fixed list of `SliverMainAxisGroup` (one for a day).
Messages for each day build lazily, because of `SliverList`, however the days don't build lazily and thus slow down rebuilds as can be seen in the screenshots below.

Executing `setState` multiple times:
With 10 days:
<img width="1561" alt="Screenshot 2024-12-11 at 09 55 31" src="https://github.com/user-attachments/assets/c27ca7f4-244b-4e23-87de-6690074f8d5a">

With 2000 days (5 - 6 years of chat history):
<img width="1558" alt="Screenshot 2024-12-11 at 09 57 05" src="https://github.com/user-attachments/assets/31be25a2-3a37-4ff0-84aa-71f0c911d749">

<details>
<summary>Example</summary>

```dart
import 'package:flutter/material.dart';
import 'package:sliver_tools/sliver_tools.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _data = List<(int, List<String>)>.generate(
    2000,
    (index) => (index, List.generate(50, (index) => index.toString())),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: _data.map((it) {
          return SliverMainAxisGroup(
            slivers: [
              SliverPinnedHeader(
                child: Container(
                  color: Colors.blue,
                  child: Text(it.$1.toString()),
                ),
              ),
              SliverList.list(
                children: it.$2.map((it) {
                  return Text(it.toString());
                }).toList(),
              )
            ],
          );
        }).toList(),
      ),
      floatingActionButton: GestureDetector(
        onTap: () => setState(() {}),
        child: Container(color: Colors.red, height: 100, width: 100),
      ),
    );
  }
}
```

</details>

**Workaround 2:**
Have a `ListView` and use a package like https://pub.dev/packages/sticky_headers where the content of the sticky header is a `Column` containing all the messages of the day.
Days build lazily, however, always all messages of that day are built, even when the day has many messages.



### Proposal

Solutions I can think of:
- Nest `SliverList` in `SliverList`
- Implement `builder` pattern for `CustomScrollView`

Both solution seem to be impossible with the current Sliver implementation, according to https://github.com/Kavantix/sliver_tools/issues/44#issuecomment-1096994549


There are some related issues. Most of them are closed without being solved:
- https://github.com/flutter/flutter/issues/97107
- https://github.com/flutter/flutter/issues/114299
- https://github.com/flutter/flutter/issues/31606