import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
var opacity = 0.0;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.purple.shade100,
body: SafeArea(
child: Stack(
children: [
NotificationListener<ScrollUpdateNotification>(
onNotification: (notification) {
final pixels = notification.metrics.pixels / 100;
setState(() {
if (pixels > 0.4) {
return;
}
opacity = pixels;
});
return true;
},
child: CustomScrollView(
slivers: [
SliverAppBar(
expandedHeight: 0,
pinned: true,
backgroundColor: Colors.black.withOpacity(opacity),
shadowColor: Colors.transparent,
title: const Text(
'Stacked Container',
style: TextStyle(
color: Colors.white,
fontSize: 22.0,
fontWeight: FontWeight.bold,
),
),
toolbarHeight: 60,
),
SliverAppBar(
clipBehavior: Clip.none,
floating: true,
toolbarHeight: 25,
shadowColor: Colors.transparent,
backgroundColor: Colors.transparent,
bottom: PreferredSize(
preferredSize: Size(double.infinity, 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(width: 15.0),
Opacity(
opacity: 1 - opacity, // Adjust the opacity based on scrolling
child: Text(
'Sliver AppBar',
style: TextStyle(
fontSize: 20.0,
color: Colors.green,
),
),
),
SizedBox(width: 15.0),
],
),
),
),
SliverList(
delegate: SliverChildListDelegate(
[
ListView.builder(
itemCount: 10,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return Container(
margin:
const EdgeInsets.fromLTRB(10.0, 20, 10, 10),
color: Colors.deepPurple,
height: 300,
width: double.infinity,
);
},
)
],
),
)
],
),
),
],
),
),
);
}
}
I’m trying to recreate Netflix appbar behavior. In this code one SliverAppBar followed by another SliverAppBar. First one is pinned second one is not. I want the part of second SliverAppBar to disappear that gets under the first SliverAppBar.
Desired:
The top half of text Sliver AppBar should disappear as it is under the first SliverAppBar.
2
Answers
After trying different ways to implement this is the closest that I could get to right now. Feel free to share if If it can be done more efficiently. With or without SliverAppBar!
Changes made are:
1, Listen to
ScrollController.offset
instead ofScrollUpdateNotification
for layouts.2, Use
SliverList.builder
for building sliver children ofCustomScrollView
. So it can be rendered lazily.3, Keep
opacity
between 0 and 1. So the assertion doesn’t throw.4, Clip the content inside
SliverAppBar
instead of constraining theSliverAppBar
. It’s easier to work withRenderBox
widget comparing toRenderSliver
widget.