NestedScrollView with Slivers Doesn't show AppBar on Scroll Up - flutter

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->

Related

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,
),
),
],
),
);
}

Flutter vertical PageView issue with SliverAppBar

I need to have the swipe effect of a vertical PageView and the effect the SliverAppBar.
If I set the scrollDirection: Axis.vertical of the PageView.builder and swipe vertical, when I swipe back I can't get the SliverAppBar.
Setting scrollDirection: Axis.horizontal the SliverAppBar works, but as mentioned I need it vertical.
I didn't found any good way to fix this yet, can you help me to understand?
My final objective is to have the first "screen" with buttons (that´s why I am using the SliverAppBar) and next screens will be a fullscreen image gallery. If you have a better solution that don´t use Slivers or PageView, please advise me.
#override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: MediaQuery.of(context).size.height*0.85,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(
'https://source.unsplash.com/random?monochromatic+dark',
fit: BoxFit.cover,
),
title: Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Row(
children: [
ElevatedButton(
onPressed: () => print('btn1'),
child: Text('Button 1')),
ElevatedButton(
onPressed: () => print('btn2'),
child: Text('Button 2')),
],
),
),
),
),
];
},
body: _pageView(),
),
);
}
_pageView() {
return PageView.builder(
scrollDirection: Axis.horizontal,
itemCount: 20,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Container(
padding: EdgeInsets.all(16.0),
child: Image.network(
'https://source.unsplash.com/random?sig=$index',
fit: BoxFit.cover,
),
),
);
},
);
}
}
If you want to view the full example or test it on your side:
https://pastebin.com/PXDHVw6k
Add SliverOverlapAbsorber before SliverAppBar;
NestedScrollView(
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
context),
sliver: SliverAppBar(
...
),
),
];
},
body: _pageView(),
),
use custom scroll wheel and using sliver.list instead of pageview and also add physics: PageScrollPhysics() to custom scroll wheel to get the same page snapping effect as pageview.
CustomScrollView(
physics: PageScrollPhysics(),
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return ... ;
},
childCount: ...,
),
),
],
),

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,
),
],
);
}),
),
);
}

Flutter: collapsing app bar with pinned tabBar

How add build collapsing app bar with pinned tabBar in Flutter like in this GIF
I managed to build it like so
class Test extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: DefaultTabController(
length: 2,
child: NestedScrollView(
headerSliverBuilder: (context, value) {
return [
SliverAppBar(
floating: true,
pinned: true,
title: Text('Test'),
bottom: TabBar(
tabs: [
Tab( text: "Call"),
Tab( text: "Message"),
],
),
),
];
},
body: TabBarView(
children: [
Container(child: ListView.builder(
itemCount: 100,
itemBuilder: (context,index){
return Text("Item $index");
})),
Container(child: ListView.builder(
itemCount: 100,
itemBuilder: (context,index){
return Text("Item $index");
})),
],
),
),
),
);
}
}
You can use the SilverAppBar
SliverAppBar(
expandedHeight: 150.0,
floating:true,
pinned: true,
flexibleSpace: const FlexibleSpaceBar(
title: Text('Available seats'),
),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.add_circle),
tooltip: 'Add new entry',
onPressed: () { /* ... */ },
),
]
)
References
SliverAppBar Class
SliverAppBar Widget of the week
Keep the TabBarView seperate from the SliverAppBar.
Make it look continuous by setting SliverAppBar's elevation to 0 and use shadow or elevation for the TabBarView, whatever you prefer.

Implementing Collapsing Toolbar in 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),
),
),
],
);
},
),
)