PageView scroll under SliverAppBar - flutter

In material 3 the AppBar changes elevation and color when there is something scrolled under it.
It works fine using CustomScrollView with a SliverList or ListView scrolling under a SliverAppBar.
The issue is when I try to use PageView instead. It works fine using a SliverFillRemaining over the PageView but the appBar won’t notice when the page is scrolled.
I tried many ways, using NestedScrollView and CustomScrollView with no success.
The only way I could achieve that was using the PageView onPageChanged to check the page and calling back the setState of my homePage to change the color and elevation programmatically but at the cost of rebuilding almost the whole tree when it reaches or leaves the 1st page.
Any insights would be appreciated.

Related

flutter make widget collapse when scroll

I want to make a container collapse (disappear) when scroll down, and expand (appear again) when scroll up. Just like the search bar in microsoft teams mobile.
I tried to do it using SliverAppBar and it worked but the ListView became lagging and had problems. Is there any way to do it without SliverAppBar?
I think you should only replace AppBar Widget with SliverAppBar
hope I could help.
You may check this library hidable

Flutter - How to Rebuild the SiverList without also rebuilding the SliverAppBar?

If I can't use a FutureBuilder inside a CustomScrollView how I can rebuild only the SliverList without also rebuilding the SliverAppBar?
I'm doing an app similar to Youtube, so like Youtube I have several buttons with the categories inside a ListView in the SliverAppBar area (Example in the image below) and a SliverList with the videos, but currently everything inside the CustomScrollView is rebuilt when I click on a category button. And the ListView inside the SliverAppBar always goes back to position 0 after rebuilding it instead of staying in the same position like Youtube.
The ideal result would be just rebuilding the SliverList. Or at least keep the ListView position (on the SliverAppBar) in the same position that was before rebuilding. How that can be done?

MaterialBanner is showing above SliverAppBar

I want to use MaterialBanner with SliverAppBar and wanted it to be displayed below the SliverAppBar like this: Banners - Material Design.
It is working fine with AppBar However, with SliverAppBar, it is displaying above the SliverAppBar. Is there a way to display it without placing it inside the Scaffold body?
You can run the DartPad here.
It seems like this behaviour is a recorded on-going issue.
Here's the issue I've created:
MaterialBanner appears above SliverAppBar
and here's the related issue:
MaterialBanner updates

How to disable animation at the edges of PageView?

I want users to scroll between pages in PageView, but I don't want to show them an animation when they try to scroll before first and after last page. I can switch between colorful animation, black animation and no scrolling, but I could not find any possibility to disable the animation at all.
If there is no such possibility, how can I change the color of that animation or make it transparent at least?
Based on your screenshot, I can say that you are using BouncingScrollPhysics for your PageView. This behavior is commonly used by iOS devices. Nonetheless, I have also reviewed the entire source code you have provided here.
What went wrong
You have added PageView without accompanying it with a Scaffold or Material widget at the top level that's why the background behind the children of the PageView is color black.
https://dartpad.dev/c709e410d0a68248ac5b387b3bc6af93
From the documentation:
Scaffold implements the basic material design visual layout structure.
Without this widget, you'll notice that your app may occupy the entire screen of your device, including the notification bar, because it (PageView) does not know where is the status bar is located in the screen.
What you can do
I noticed that all of the children added inside the PageView has individual Scaffold and AppBar, it's not really necessary to nest scaffolds and you may want to use TabBarView instead of PageView, and let the parent widget handle the AppBar changes via TabController.
But if you think it'll cost you too much effort to refactor, feel free to review the following options that require minimal changes which will suit your needs:
Option 1. You can wrap your widget inside a Scaffold widget.
https://dartpad.dev/4620ff91444353f5e000d2063594bd96
Option 2. Given that nesting Scaffold widgets is not a good practice, you can just use the plain Material widget to wrap your PageView with children wrapped with Scaffold widget.
https://dartpad.dev/43f8730e5592ce1f96193fc01f08a29c
These solutions will change the background color of the PageView from black to white.
Option 3. If you really want to get rid of the animation, the easiest way to hack it is changing your scroll physics:
physics: ClampingScrollPhysics(),
However, this still has a glowing or ripple effect when you try to swipe at the end of the screen.
To further get rid of this effect, I'll share with you these SO answers:
How to remove scroll glow? (works for Android)
How to remove overscroll on ios? (works for iOS)
Further reading
https://api.flutter.dev/flutter/widgets/ScrollPhysics-class.html
https://medium.com/flutter-community/custom-scroll-physics-in-flutter-3224dd9e9b41

Differences between SliverList vs ListView in Flutter

What are the differences between SliverList and ListView in Flutter?
There's almost no difference.
ListView is a SliverList. Same with GridView, which is a SliverGrid.
They are doing exactly the same thing. The only difference between them is that SliverList is a sliver, not a widget. Which means it's used inside a ScrollView, usually CustomScrollView.
ListView is nothing else but a biding of SliverList to transform it into a Widget to make it usable alongside other widgets such as Row/Container.
Most of the time, use ListView.
But if you want advanced scroll behavior such as appbar animations with scroll ; you'll need to use a CustomScrollView. Which will force you to use SliverList instead of ListView.
According this article,
All of the scrollable views you use, like ListView and GridView,
are actually implemented using Slivers. You can kind of think of
Slivers as a lower-level interface, providing finer-grained control on
implementing scrollable area. Because slivers can lazily build each
item just as it scrolls into view, slivers are particularly useful for
efficiently scrolling through large numbers of children.