Implementing Collapsing Toolbar in Flutter - flutter

I am trying to implement collapsing toolbar in my app using SliverApp bar, but the problem is that the SliverAppBar is overlapping my content when the SliverAppBar is collapsed, I am attaching the gif for more understanding,
the content in the green background is going under the toolbar, I want to avoid that, any leads are appreciated.
#override
Widget build(BuildContext context) {
// TODO: implement buildr
var _tabs = {"1", "2", "3"};
return Scaffold(
backgroundColor: Colors.white,
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverOverlapAbsorber(
handle:
NestedScrollView.sliverOverlapAbsorberHandleFor(context),
child: SliverAppBar(
expandedHeight: 250.0,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
background: Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
image: DecorationImage(
fit: BoxFit.fill,
image: CachedNetworkImageProvider(
newsPost.photos[0].url),
),
),
)),
forceElevated: innerBoxIsScrolled,
))
];
},
body: SafeArea(
top: false,
bottom: false,
child: Builder(
builder: (BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
context),
),
SliverPadding(
padding: const EdgeInsets.all(8.0),
sliver: SliverFillRemaining(child: _getBody()),
),
],
);
},
),
)),
);
}

SliverAppBar Creates a material design app bar that can be placed in a NestedScrollView. Both combinly help us in achieving parallax scrolling.
SafeArea(
child: Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 240.0,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
title: Text(
"App Bar",
),
background: Image.network(
"https://images.pexels.com/photos/4148020/pexels-photo-4148020.jpeg",
fit: BoxFit.cover,
)),
),
];
},
body: Center(
child: Text("Hello World!!!"),
),
),
),
);

I think you should use SliverList instead of SliverFillRemaining.
body: SafeArea(
top: false,
bottom: false,
child: Builder(
builder: (BuildContext context) {
return CustomScrollView(
shrinkWrap: true,
slivers: <Widget>[
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
context),
),
SliverPadding(
padding: const EdgeInsets.all(0.0),
sliver: SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return Text('Lorem ipsum dolor sit');
}, childCount: 1),
),
),
],
);
},
),
)

Related

Flutter - Unwanted padding below SliverAppBar

How do I remove the space below a SliverAppBar above the body? I know it is the SliverAppBar causing the space because the padding only gets removed when I remove that:
Widget buildScrollable(BuildContext context) {
return Scaffold(
body: NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverPadding(
padding: EdgeInsets.zero,
sliver: SliverAppBar(
toolbarHeight: widget.toolbarHeight ?? _appBarHeight,
systemOverlayStyle: SystemUiOverlayStyle.dark,
brightness: Brightness.light,
actions: [
Container(
width: widget.leadingWidth ?? APP_BAR_LEADING_WIDTH,
)
],
leading: Padding(
padding: const EdgeInsets.only(left: STANDARD_PAD),
child: widget.leading),
leadingWidth: widget.leadingWidth ?? APP_BAR_LEADING_WIDTH,
centerTitle: true,
title: BlMeasureSize(
onChange: (size) {
setState(() {
_appBarHeightOrNull =
size.height < APP_BAR_MIN_HEIGHT
? APP_BAR_MIN_HEIGHT
: size.height;
});
},
child: widget.title),
pinned: false,
stretch: true,
flexibleSpace: FlexibleSpaceBarSettings(
toolbarOpacity: 1,
currentExtent: _appBarHeight,
maxExtent: _appBarHeight,
minExtent: _appBarHeight,
child: FlexibleSpaceBar(
background: Container(
decoration: const BoxDecoration(
gradient: edenYellowGradient,
),
))),
bottom: widget.bottom,
))
];
},
physics: ClampingScrollPhysics(),
body: Builder(
builder: ((context) {
_scrollController.addListener(_scrollListener);
return Stack(children: [
SlideTransition(
position: _offsetAnimation,
child: Container(
height: _appBarHeight,
decoration: const BoxDecoration(
gradient: edenYellowGradient,
),
)),
SafeArea(child: widget.body)
]);
}),
)),
);
}
I've tried SliverPadding, ClampingScrollPhysics and PreferredSize. I can't do MediaQuery.removePadding because it disables the SafeArea.

Using FutureBuilder with SliverAppBar

I am newbie and I am still trying to get Widgets and wrapping concept. For me it is probably hardest part of to learn Flutter.
I have Sliver AppBar and I have to get fetch some data and using FutureBuilder. Here is code
#override
Widget build(BuildContext context) => Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
backgroundColor: Colors.red,
expandedHeight: 200,
floating: true,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(
'https://source.unsplash.com/random?monochromatic+dark',
fit: BoxFit.cover,
),
title: Text('Flexible Title'),
centerTitle: true,
),
//title: Text('My App Bar'),
leading: Icon(Icons.arrow_back),
actions: [
Icon(Icons.settings),
SizedBox(width: 12),
],
),
],
),
);
}
so my problem is how can I integrate my FutureBuilder snippet to this code.
Here is FutureBuilder:
FutureBuilder<Article>(
future: _futureArticle,
builder: (BuildContext context, AsyncSnapshot<Article> snapshot) {
if (snapshot.hasData) {
final article = snapshot.data?.data;
any help
The correct wrapping:
Widget build(BuildContext context) => Scaffold(
body: FutureBuilder<Article>(
future: _futureArticle,
builder: (BuildContext context, AsyncSnapshot<Article> snapshot) {
if (snapshot.hasData) {
final article = snapshot.data?.data;
return CustomScrollView(
slivers: [
SliverAppBar(
// backgroundColor: Colors.red,
expandedHeight: 200,
floating: true,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(article == null
? 'https://www.tonymacx86.com/attachments/2019-02-05-07-50-43-jpeg.385401/'
: article.imageUrl!),
title: Text('${article!.title}'),
centerTitle: true,
),
leading: const Icon(Icons.arrow_back),
actions: const [
Icon(Icons.settings),
SizedBox(width: 12),
],
),
],
);
}
return const Center(
child: CircularProgressIndicator(),
);
},
),
);
}

NestedScrollView with Slivers Doesn't show AppBar on Scroll Up

I'm using NestedScrollView in order to achieve scroll show appbar gesture on myApp. Not sure what could be the issue, once scrolled down, doesnt show up again til you restart .
body:
NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
sliver: SliverAppBar(
backgroundColor: Colors.red,
floating: true,
pinned: true,
toolbarHeight: 80,
automaticallyImplyLeading: false,
bottom:
PreferredSize(
preferredSize: Size.fromHeight(0),
child: new Offstage(),
),
elevation: 0,
actions: <Widget>[
// Icons
],
),
),
];
},
body:
SafeArea(
child: PageView(
controller: _pageController,
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
UserListPage(),
MerchantListPage(),
],
),
),
),
Try below code hope its helpful to you. set pinned: true, inside SliverAppBar() widget refer NestedScrollView here
return Scaffold(
body: NestedScrollView(
floatHeaderSlivers: true,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
title: const Text('NestedScrollView'),
pinned: true,
expandedHeight: 200.0,
forceElevated: innerBoxIsScrolled,
),
];
},
body: ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: 30,
itemBuilder: (BuildContext context, int index) {
return SizedBox(
height: 50,
child: Center(child: Text('Item $index')),
);
},
),
),
);
Your result screen->

How to make Whatsapp like appbar in flutter

I'm creating an app where I need to implement WhatsApp like AppBar i.e to hide app bar on scroll down and show on reverse.
You can use the SliverAppBar and CustomScrollView to achieve this effect. A sample implementation:
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: false,
snap: false,
floating: false,
expandedHeight: 160.0,
flexibleSpace: const FlexibleSpaceBar(
title: Text('AppBar'),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
color: index.isOdd ? Colors.white : Colors.black12,
height: 100.0,
child: Center(
child: Text('$index', textScaleFactor: 5),
),
);
},
childCount: 50,
),
),
],
),
);
}

How can I put Scroll glow in a sliverList instead of customScrollView?

The glow acts like the entire screen is a list. There some way that I can put the glow below the appbar? (edit: without losing the floating effect of the appbar)
CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: Text('Home Scree'),
floating: true,
leading: Icon(Icons.alarm),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, i) {
return Column(
children: <Widget>[
ProductCard(),
Divider(
height: 0,
thickness: 1,
),
],
);
},
childCount: 10,
),
),
],
),
Maybe you can try to use NestedScrollView,like this:
#override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [SliverAppBar(
leading: Icon(Icons.alarm),
title: Text('Home Scree'),
expandedHeight: kToolbarHeight,
floating: true,
)];
},
body: ListView.builder(
padding: EdgeInsets.zero,
itemCount: 10,
itemBuilder: (context, index) {
return Column(
children: <Widget>[
ProductCard(),
Divider(
height: 0,
thickness: 1,
),
],
);
}),
),
);
}