SliverAppBar in reversed CustomScrollView - flutter

I am building a chat app and I want new chat messages arrive from the bottom of the SliverList. As well I want the SliverAppBar to scroll out of view (floating) when the scroll view starts scrolling when enough messages have arrived.
I am using a reversed CustomScrollView with an SliverAppBar and a SliverList:
CustomScrollView(
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
reverse: true,
controller: _scrollController,
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return _messages[index];
},
childCount: _messages.length,
),
),
SliverAppBar(
title: Text('Chat App'),
centerTitle: true,
floating: true,
),
],
),
This way the SliverAppBar is on top of the SliverList, but not at the top of the screen. Is it possible to set the SliverAppBar to the top of the screen as if it was not reversed?

Related

How to use auto route with scrollable view in flutter

I am using Flutter to create a Web app.
How can i create a layout_view using the package auto_route that can be scrolled with a single scroll parent. In a way that i don't need to add scroll views on child and create multiple scroll points and bars.
I did something like this:
Scaffold(
backgroundColor: Constants.backgroundColor,
body: CustomScrollView(
primary: true,
slivers: <Widget>[
SliverAppBar(
expandedHeight: Responsive.isSmallScreen(context) ? 93 : 196.0,
backgroundColor: Colors.transparent,
flexibleSpace: const FlexibleSpaceBar(
background: AppBarView(),
),
),
SliverFillRemaining(
hasScrollBody: true,
child: Column(
children: const [
Expanded(child: AutoRouter()),
],
),
)
],
),
)
The problem is that if the AutoRouter is bigger than the remained viewport the bottom is overflowed and i can't scroll. I tried to add SingleChildScrollView as parent of AutoRouter but it doesn't render
I don't want to repeat the AppBarView on all screens, that's why i am using a layout view with an auto router. But at the same time i want to scroll de AppBar along with the rest of the screen.
[ ]'s

Flutter smoothly scaling app bars title on scroll

for now I have mock of view as presented. I want this app bars title to be twice as big when I'm on the top of the screen with no buttons, and scale smoothly back to current form with two buttons when I scroll down. I tried to experiment with sliverappbar but without effect. I use here scaffold with standard app bar. Is there a convenient way to achieve it, or I have to write it myself. I'd be thankful for any advice.
EDIT: Something like showed here gif
You can use CustomScrollView with Slivers to achieve your desired result. I'm sharing an example for this you can customize it as per your need.
CustomScrollView(
slivers: [
SliverAppBar(
pinned: true,
expandedHeight: 120,
flexibleSpace: FlexibleSpaceBar(
title: Text("Barb's Latest",style: TextStyle(fontSize: 30),),titlePadding: EdgeInsets.all(15),
),automaticallyImplyLeading: true,
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Container(
height: 100,
margin: EdgeInsets.only(bottom: 10),
color: Colors.red,
),
childCount: 50))
],
)

Gridview within a TabBarview that moves a sliver app bar

Hi I was wondering it is possible to have a grid view within a tabbarview which has properties of a sliver so it moves the app bar.
I have a grid view within a tabbarview however it does not cause the tab bar to collapse
This is my code so far
NestedScrollView(
headerSliverBuilder: (context, value) {
return SliverAppBar(
backgroundColor: Colors.white,
floating: true,
pinned: false,
stretch: false,
snap: false,
(...)///Collapsible space etc
);
},
body: TabBarView(
children: [
///Other widgets
(...)
///My gridview
GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
children: List.generate(10, (index) {
return Container(
height: 100.0,
width: 100.0,
color: Colors.pink,
child: Text(index.toString()),
);
}),
)
]
)
)
Edit Below
[EDIT]
Set shrinkWrap to true
Sets physics to NeverScrollableScrollPhysics()
set shrinkWrap to true and physics to NeverScrollableScrollPhysics() to your GridView.
This is useful when you add a scrollable widget inside another scrollable widget.

Flutter docs are very confusing, what's the use of SliverOverlapAbsorber and SliverOverlapInjector?

I am using this example from flutter official docs. Here is the minimal code:
List<String> _tabs = ["Tab1", "Tab2"];
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: _tabs.length,
child: Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
// 1/2 remove this widget and only use SliverAppBar
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
child: SliverAppBar(
title: const Text('Books'),
pinned: true,
expandedHeight: 150.0,
bottom: TabBar(tabs: _tabs.map((name) => Tab(text: name)).toList()),
),
),
];
},
body: TabBarView(
children: _tabs.map((String name) {
return Builder(
builder: (BuildContext context) {
return CustomScrollView(
key: PageStorageKey<String>(name),
slivers: <Widget>[
// 2/2 remove this widget
SliverOverlapInjector(handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context)),
SliverFixedExtentList(
itemExtent: 48.0,
delegate: SliverChildBuilderDelegate(
(_, i) => ListTile(title: Text('Item $i')),
childCount: 30,
),
)
],
);
},
);
}).toList(),
),
),
),
);
}
Problem:
As you can see if I remove SliverOverlapAbsorber along with SliverOverlapInjector in above code, I don't see any change in the output, what's the use of having it? Docs say
SliverOverlapInjector: This widget takes the overlapping behavior of the SliverAppBar, and redirects it to the SliverOverlapInjector below. If it is missing, then it is possible for the nested "inner" scroll view below to end up under the SliverAppBar even when the inner scroll view thinks it has not been scrolled. This is not necessary if the "headerSliverBuilder" only builds widgets that do not overlap the next sliver.
Can anyone explain what does it mean and what's the use of having SliverOverlapInjector and SliverOverlapInjector
I use it in NestedScrollView
NestedScrollView(
headerSliverBuilder: (context, innerBoxIsScrolled) => [
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
sliver: SliverAppBar()
],
body: ...
)
Without it everything in your body will go under appbar.
Check out https://api.flutter.dev/flutter/widgets/NestedScrollView-class.html
It's said there
SliverOverlapAbsorber(
// This widget takes the overlapping behavior of the SliverAppBar,
// and redirects it to the SliverOverlapInjector below. If it is
// missing, then it is possible for the nested "inner" scroll view
// below to end up under the SliverAppBar even when the inner
// scroll view thinks it has not been scrolled.
// This is not necessary if the "headerSliverBuilder" only builds
// widgets that do not overlap the next sliver.
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),

Using flexible SliverAppBar as non-top element

I'm trying to display a flexible SliverAppBar below a custom app bar (let's say it's a container with a height of 80.0).
When making the SliverAppBar the top element, it works fine, but when it's the second one, there is a top-padding as big as the Android UI interface.
Scaffold(
body: Column(children: <Widget>[
Container(height: 80.0),
Expanded(child: _content())
]),
);
_content()
return CustomScrollView(slivers: <Widget>[
SliverAppBar(
backgroundColor: Colors.red,
leading: PopContentButton(),
title: Text('Test'),
snap: true,
pinned: true,
floating: true,
bottom: TabBar(
tabs: _tabs(),
controller: TabControllerExtended(length: 4, vsync: this),
),
),
SliverList(delegate: new SliverChildListDelegate(buildTextViews(50)))
]);
This is not how it should look:
(source: bilder-upload.eu)
It should look like:
(source: bilder-upload.eu)
Wrap you - SliverAppBar with MediaQuery.removePadding.
Updated Code :
....
MediaQuery.removePadding(
context: context,
removeTop: true,
child: SliverAppBar(
...