I have a CustomScrollView with a SliverAppBar and some slivers. I want to overlay some graphics on the SliverAppBar and have them scroll with the rest of the list.
Here's the code I've been working with:
import 'package:flutter/material.dart';
void main() async {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: SliverTest(),
);
}
}
class SliverTest extends StatefulWidget {
const SliverTest({super.key});
@override
State<SliverTest> createState() => _SliverTestState();
}
class _SliverTestState extends State<SliverTest> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
expandedHeight: 350.0,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
background: Container(
color: Colors.yellow,
child: const Center(child: Text('My Parallax Image!')),
),
),
),
SliverToBoxAdapter(
child: Container(
height: 100,
color: Colors.blueAccent,
child: Stack(
children: [
Align(
alignment: const Alignment(0.0, -2.0),
child: Container(
width: 50,
height: 50,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
child: const Center(child: Text('Red')),
),
),
],
),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
height: 50,
color: Colors.teal[100 * ((index % 8) + 1)],
child: Center(child: Text('Item #$index')),
);
},
childCount: 20,
),
),
],
),
),
);
}
}
In this setup, I want the red circle (which is currently clipped) to be drawn on top of the yellow section of the SliverAppBar (Please note that the yellow section is just a simple placeholder for some actual images with parallax effect, and the use of a solid yellow color is merely for simplicity's sake). I've placed the red circle inside a sliver because I want it to scroll along with the rest of the list when the user interacts with the scrollable area.
Could anyone provide a simple example of how to achieve this in Flutter? I'm open to any other solutions that utilize slivers, as they provide huge convenience to the other parts of my real app. Otherwise, I'm aware that I may recreate it without utilizing the slivers. Any help would be greatly appreciated. Thanks in advance!



You might consider using a
Stackwidget to overlay the graphic on top of theSliverAppBar. The challenge is, however, to make the graphic scroll along with theCustomScrollView. You can try and adjust the position of the graphic in response to the scroll offset of theCustomScrollView.Use a
NotificationListenerto listen to scroll events. Calculate the position of the graphic based on the scroll offset. Use aStackand adjust the position of the graphic dynamically as the user scrolls.You can see the
NotificationListenerlistening to scroll events and updating the_offsetvariable. TheStackwidget overlays the red circle over theCustomScrollView. And thePositionedwidget adjusts the position of the red circle based on the scroll offset.See if that would place the red circle on top of the
SliverAppBarand make it scroll with the rest of the list.To address the requirements of having the red circle scroll along with the slivers and also appear behind the
SliverAppBar, you can try and use aCustomScrollViewwith aSliverPersistentHeader. TheSliverPersistentHeaderwill allow you to create a custom header that behaves like aSliverAppBarbut with more control over its contents and layout.So, create a
SliverPersistentHeaderthat includes the yellow background and the red circle. Adjust the position of the red circle within the custom header so that it initially appears in the desired location but still scrolls with the rest of the content. By using aSliverPersistentHeader, the red circle should naturally be placed behind theSliverAppBaras it scrolls.The
SliverAppBarshould remain pinned at the top, and the custom header scrolls up underneath it.Check if you see the red circle scroll with the rest of the list and stay behind the
SliverAppBar.