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"),
),
)
],
),
)
),
),
);
}
}
Is there an existing issue for this?
Steps to reproduce
I have a
NestedScrollViewwith aSliverAppBar, and aCustomScrollViewas a child. Inside theCustomScrollView, if I use aSliverList.buildereverything works fine, but if I use aSliverList.listthe scroll doesn't work. This only happens with the normalSliverAppBar. If you use aSliverAppBar.mediumor aSliverAppBar.large, both SliverLists works fine.Expected results
Scrolling with
SliverList.listshould scroll as it doesSliverList.builder.Actual results
SliverList.builderscrolls butSliverList.listdoesn't.Code sample
In case you wonder why I want to use a
SliverList.listinstead of aSliverList.builderit'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
Screenshots or Video
Screenshots / Video demonstration
scroll-issue.mp4
Logs
No response
Flutter Doctor output
Doctor output