I have NestedScrollView as such:
headers: [
SliverToBox(), // This scrolls away
SliverPersistentHeader(), // This needs to pin
]
body: TabBarView() // Classic TabBar view with multiple pages
This is how it looks unscrolled:
This is how it looks when I start scrolling 1st page (all good so far):
And this is how it looks when I swipe to the next tab. Notice that the next page is already scrolled a little bit (starts from 2 and it should start from 0). The difference is in height of PersistentSliverHeader, basically second page gets scrolled underneath the header. How can I make the scroll on page 1 not affect the scroll on page 2?
Code: Here is the Gist, unfortunately it doesn't work on web/dartpad but on mobile runs without issues: https://gist.github.com/itsJoKr/eca5b57c2f290f517862dcd118a16d4d
Answer was to use SliverOverlapAbsorber
.
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
sliver: SliverPersistentHeader(
pinned: true,
delegate: ChipTabBarSliverDelegate2(
tabController,
[
'tab 1',
'tab 2',
'tab 3',
],
MediaQuery.of(context).padding.top,
),
),
),
And key this is handle. It's exactly for this as it says in the docs:
// 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.