Skip to content

Scroll not working on a SliverList.list inside a CustomScrollView, but yes with a SliverList.builder #127282

@JGeek00

Description

@JGeek00

Is there an existing issue for this?

Steps to reproduce

I have a NestedScrollViewwith a SliverAppBar, and a CustomScrollView as a child. Inside the CustomScrollView, if I use a SliverList.builder everything works fine, but if I use a SliverList.listthe scroll doesn't work. This only happens with the normal SliverAppBar. If you use a SliverAppBar.mediumor a SliverAppBar.large, both SliverLists works fine.

Expected results

Scrolling with SliverList.listshould scroll as it does SliverList.builder.

Actual results

SliverList.builder scrolls but SliverList.listdoesn't.

Code sample

In case you wonder why I want to use a SliverList.list instead of a SliverList.builder it's because I want to build a settings screen, with a list of different options. The list is built with widgets with different structures, it's not a list with the same widget but with different data, so that's why I want to use a normal SliverList.list instead a SliverList.builder.

Code sample
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

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

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      theme: ThemeData(
        useMaterial3: true
      ),
      home: const MyStatelessWidget(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            SliverOverlapAbsorber(
              handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
              sliver: SliverAppBar(
                title: const Text("Title"),
                pinned: true,
                floating: true,
                centerTitle: false,
                forceElevated: innerBoxIsScrolled,
              ),
            ),
          ];
        },
        body: SafeArea(
          top: false,
          bottom: false,
          child: Builder(
            builder: (context) => CustomScrollView(
              slivers: [
                SliverOverlapInjector(
                  handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                ),
                SliverList.list(
                  children: [
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                    ListTile(
                      title: const Text("List tile"),
                      subtitle: const Text("Navigate to second screen"),
                      onTap: () => Navigator.push(context, MaterialPageRoute(
                        builder: (context) => const SecondScreen()
                      )),
                    ),
                  ]
                ),
                // SliverList.builder(
                //   itemCount: 30,
                //   itemBuilder: (context, index) => ListTile(
                //     title: Text("List tile $index"),
                //     subtitle: const Text("Navigate to second screen"),
                //     onTap: () => Navigator.push(context, MaterialPageRoute(
                //       builder: (context) => const SecondScreen()
                //     )),
                //   ) 
                // )
              ],
            ),
          )
        )
      ),
    );
  }
}

class SecondScreen extends StatefulWidget {
  const SecondScreen({Key? key}) : super(key: key);

  @override
  State<SecondScreen> createState() => _SecondScreenState();
}

class _SecondScreenState extends State<SecondScreen> {
  int count = 30;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (context, innerBoxIsScrolled) => [
          SliverOverlapAbsorber(
            handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
            sliver: SliverAppBar.large(
              leading: IconButton(
                onPressed: () => Navigator.pop(context), 
                icon: const Icon(Icons.close)
              ),
              pinned: true,
              floating: true,
              centerTitle: false,
              forceElevated: innerBoxIsScrolled,
              title: const Text("Second screen"),
              actions: [
                IconButton(
                  onPressed: () => setState(() => count++), 
                  icon: const Icon(Icons.add)
                ),
                const SizedBox(width: 10)
              ],
            ),
          )
        ],
        body: SafeArea(
          top: false,
          bottom: false,
          child: Builder(
            builder: (context) => CustomScrollView(
              slivers: [
                SliverOverlapInjector(
                  handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                ),
                SliverList.builder(
                  itemCount: count,
                  itemBuilder: (context, index) => ListTile(
                    title: Text("Item $index"),
                  ),
                )
              ],
            ),
          ) 
        ),
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration
scroll-issue.mp4

Logs

No response

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.10.1, on macOS 13.3.1 22E772610a darwin-arm64, locale es-ES)
    • Flutter version 3.10.1 on channel stable at /Users/juan/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision d3d8effc68 (4 days ago), 2023-05-16 17:59:05 -0700
    • Engine revision b4fb11214d
    • Dart version 3.0.1
    • DevTools version 2.23.1

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /Users/juan/Library/Android/sdk
    • Platform android-33, build-tools 31.0.0
    • ANDROID_HOME = /Users/juan/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E222b
    • CocoaPods version 1.11.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301)

[✓] VS Code (version 1.78.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.60.0

[✓] Connected device (4 available)
    • sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64  • Android 13 (API 33) (emulator)
    • sdk gphone64 arm64 (mobile) • emulator-5556 • android-arm64  • Android 12 (API 31) (emulator)
    • macOS (desktop)             • macos         • darwin-arm64   • macOS 13.3.1 22E772610a darwin-arm64
    • Chrome (web)                • chrome        • web-javascript • Google Chrome 113.0.5672.126

[✓] Network resources
    • All expected network resources are available.

• No issues found!```

</details>

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work listf: scrollingViewports, list views, slivers, etc.found in release: 3.10Found to occur in 3.10found in release: 3.11Found to occur in 3.11frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionwaiting for PR to land (fixed)A fix is in flight

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions