Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NestedScrollView : is there any way to support multiple child for SliverOverlapAbsorber #22393

Closed
zmtzawqlp opened this issue Sep 28, 2018 · 33 comments
Assignees
Labels
c: new feature Nothing broken; request for a new capability f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels. P3 Issues that are less important to the Flutter project

Comments

@zmtzawqlp
Copy link
Contributor

As [flutter document(https://docs.flutter.io/flutter/widgets/NestedScrollView-class.html) said about 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.

SliverOverlapAbsorber can fix the Scroll postion in body scroll widget. is there any way to support
multiple child. as i use a pinned SliverPersistentHeader under a SliverOverlapAbsorber
more info please see the gif and demo code. thanks

373096261108bffd940561f8af23535c
main6.zip

@zoechi zoechi added framework flutter/packages/flutter repository. See also f: labels. f: scrolling Viewports, list views, slivers, etc. labels Sep 28, 2018
@zoechi zoechi added this to the Goals milestone Sep 28, 2018
@zmtzawqlp
Copy link
Contributor Author

zmtzawqlp commented Nov 15, 2018

i have done some things to solve this thing, may be you have better solution 。please check it when you have the time.
i notice outerscrollcontrol will handle the pinned scroll extend, so i done some to fix it.
https://github.com/fluttercandies/extended_nested_scroll_view

@zmtzawqlp zmtzawqlp changed the title is there any way to support multiple child for SliverOverlapAbsorber NestedScrollView : is there any way to support multiple child for SliverOverlapAbsorber Dec 20, 2018
@vanlooverenkoen
Copy link
Contributor

vanlooverenkoen commented Aug 6, 2019

Any progress on this issue? This should be fixed in the flutter itself as well

@shinvi
Copy link

shinvi commented Aug 26, 2019

It’s already in the second half of 2019, and I still haven’t seen any progress on this issue. T_T

@Piinks Piinks added the c: new feature Nothing broken; request for a new capability label Jan 23, 2020
@hahnrobert
Copy link

@vanlooverenkoen I don't understand why this ticket was closed. This ticket is definitely not addressed as of today.
Flutter provides no solution to absorb the height of more than one child. This limits design abilities as no fixed size element can be used between the AppBar and the scrolling content of a child.

@kf6gpe kf6gpe added the P2 Important issues not at the top of the work list label May 29, 2020
@bikashKatwal
Copy link

I am still having this issue, it is not yet resolved from flutter

@ngxingyu
Copy link

My approach: use MultiSliver widget from sliver_tools 0.1.8 to wrap the multiple slivers within SliverOverlapAbsorber. Any other possible approaches at the moment?

@engineerdeep
Copy link

Still facing this issue, any updates?

@ayush-12
Copy link

I am also facing this issue. @zoechi is there any update on this issue?

@xiagaizhi
Copy link

me too

@msangals
Copy link

msangals commented May 8, 2021

any updates?

@aradhwan
Copy link

I'm facing the same issue.

@hosseinshaya
Copy link

I'm still facing this issue

@Piinks
Copy link
Contributor

Piinks commented Jun 2, 2021

I have not tried this yet, but it occurred to me this morning that the sliver_tools package may resolve this. You could use the sliver group - MultiSliver I think - to group more one sliver together and then wrap it in the the SliverOverlapAbsorber.

@martipello
Copy link

sliver_tools

totally works many thanks

@vanlooverenkoen
Copy link
Contributor

@Piinks the sliver_tools is a workaround right? This should still be fixed in flutter itself as well?

@MinseokKang003
Copy link

I'm also facing this issue.
Also If I put another sliver above SliverOverlapAbsorber, it works fine but the scrolling speed becomes inconsistent when body starts to scroll.
Hope to see updates.

@Piinks
Copy link
Contributor

Piinks commented Jun 7, 2021

@Piinks the sliver_tools is a workaround right? This should still be fixed in flutter itself as well?

Hey @vanlooverenkoen I am not sure! At this time there is no one actively working on this, but the issue remains open. :)

@JPM84
Copy link

JPM84 commented Jun 20, 2021

This feature would be really helpful!

@darkstarx
Copy link

MultiSliverOverlapAbsorber is a bad solution because I need another sliver between two (or more) SliverAppBars. The best solution is to allow several SliverOverlapAbsorbers with a single handle.

@devbytyler
Copy link

Also need this feature

@StanevPrime
Copy link

It will be great to have this feature!

@popalexandru
Copy link

hello, one solution is to use a SliverOverlapAbsorber with pinned = true
like here: https://api.flutter.dev/flutter/widgets/NestedScrollView-class.html

@vbuberen
Copy link

@popalexandru Could you add an example of how it would look like. Was just refactoring code on one project I recently joined and it had SliverOverlapAbsorber, which, unfortunately, didn't help with the discussed issue.

@rikai-trongpq
Copy link

hello, one solution is to use a SliverOverlapAbsorber with pinned = true like here: https://api.flutter.dev/flutter/widgets/NestedScrollView-class.html

These example seem it work but ListView inside each tab will affect for all tab when you scroll one of them.

@Divinoart
Copy link

Divinoart commented Mar 6, 2022

Using MultiSliver worked out fine for me.

SliverOverlapAbsorber(
    handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
    sliver: MultiSliver(
      pushPinnedChildren: false, // defaults to false
      children: <Widget>[
        SliverPersistentHeader(
          pinned: true,
          floating: false,
          delegate: AppbarDelegateWidget(),
        ),
        SliverAppBar(
          elevation: 0,
          automaticallyImplyLeading: false,
          backgroundColor: Theme.defaultColorBg,
          pinned: false,
          floating: false,
          snap: false,
          expandedHeight: 200,
          forceElevated: innerBoxIsScrolled,
          flexibleSpace: FlexibleSpaceBar(
            background: Container(
              color: Theme.defaultColorBg,
              width: MediaQuery.of(context).size.width,
              child: DashBoardGraph(),
            ),
          ),
        ),
        SliverPersistentHeader(
          pinned: true,
          floating: false,
          delegate: DashboardTabBarDelegate(onTap: (int index) {
            injector<DashboardViewModel>().jumpToTopOfPage();
          }),
        ),
      ],
    ),
  ),

Additionally, you might want to wrap the body with a SliverSafeArea or top padding.

@EArminjon
Copy link
Contributor

Using MultiSliver worked out fine for me.

SliverOverlapAbsorber(
    handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
    sliver: MultiSliver(
      pushPinnedChildren: false, // defaults to false
      children: <Widget>[
        SliverPersistentHeader(
          pinned: true,
          floating: false,
          delegate: AppbarDelegateWidget(),
        ),
        SliverAppBar(
          elevation: 0,
          automaticallyImplyLeading: false,
          backgroundColor: Theme.defaultColorBg,
          pinned: false,
          floating: false,
          snap: false,
          expandedHeight: 200,
          forceElevated: innerBoxIsScrolled,
          flexibleSpace: FlexibleSpaceBar(
            background: Container(
              color: Theme.defaultColorBg,
              width: MediaQuery.of(context).size.width,
              child: DashBoardGraph(),
            ),
          ),
        ),
        SliverPersistentHeader(
          pinned: true,
          floating: false,
          delegate: DashboardTabBarDelegate(onTap: (int index) {
            injector<DashboardViewModel>().jumpToTopOfPage();
          }),
        ),
      ],
    ),
  ),

Additionally, you might want to wrap the body with a SliverSafeArea or top padding.

Not working when using multiple SliverAppBar pinned with flexibleSpaceBar.

@EArminjon
Copy link
Contributor

This code support double sliver pinned appbar without the issue where small body go behind second app bar.

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Home(),
    ),
  );
}

class Home extends StatelessWidget {
  Home({super.key});

  final SliverOverlapAbsorberHandle appBar = SliverOverlapAbsorberHandle();
  final SliverOverlapAbsorberHandle disconnectBar =
      SliverOverlapAbsorberHandle();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: NestedScrollView(
        physics: const ClampingScrollPhysics(),
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) =>
            <Widget>[
          SliverOverlapAbsorber(
            handle: appBar,
            sliver: const SliverAppBar(
              pinned: true,
              backgroundColor: Colors.red,
              elevation: 0,
              toolbarHeight: 50,
              expandedHeight: 100,
              title: Center(
                child: Text("First pinned appbar"),
              ),
            ),
          ),
          SliverOverlapAbsorber(
            handle: disconnectBar,
            sliver: const SliverAppBar(
              pinned: true,
              backgroundColor: Colors.green,
              elevation: 0,
              primary: false,
              toolbarHeight: 20,
              expandedHeight: 100,
              title: Center(
                child: Text("Second pinned appbar"),
              ),
            ),
          ),
        ],
        body: Builder(
          builder: (BuildContext context) => CustomScrollView(
            slivers: <Widget>[
              SliverOverlapInjector(handle: appBar),
              SliverOverlapInjector(handle: disconnectBar),
              SliverToBoxAdapter(
                child: Container(
                  color: Colors.grey,
                  height: 100,
                  width: double.infinity,
                  child: const Center(child: Text("body")),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

untitled

@Angeloqo
Copy link

This code support double sliver pinned appbar without the issue where small body go behind second app bar.

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Home(),
    ),
  );
}

class Home extends StatelessWidget {
  Home({super.key});

  final SliverOverlapAbsorberHandle appBar = SliverOverlapAbsorberHandle();
  final SliverOverlapAbsorberHandle disconnectBar =
      SliverOverlapAbsorberHandle();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: NestedScrollView(
        physics: const ClampingScrollPhysics(),
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) =>
            <Widget>[
          SliverOverlapAbsorber(
            handle: appBar,
            sliver: const SliverAppBar(
              pinned: true,
              backgroundColor: Colors.red,
              elevation: 0,
              toolbarHeight: 50,
              expandedHeight: 100,
              title: Center(
                child: Text("First pinned appbar"),
              ),
            ),
          ),
          SliverOverlapAbsorber(
            handle: disconnectBar,
            sliver: const SliverAppBar(
              pinned: true,
              backgroundColor: Colors.green,
              elevation: 0,
              primary: false,
              toolbarHeight: 20,
              expandedHeight: 100,
              title: Center(
                child: Text("Second pinned appbar"),
              ),
            ),
          ),
        ],
        body: Builder(
          builder: (BuildContext context) => CustomScrollView(
            slivers: <Widget>[
              SliverOverlapInjector(handle: appBar),
              SliverOverlapInjector(handle: disconnectBar),
              SliverToBoxAdapter(
                child: Container(
                  color: Colors.grey,
                  height: 100,
                  width: double.infinity,
                  child: const Center(child: Text("body")),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

untitled untitled

worked out fine for me!! thanks!!

@nerder
Copy link

nerder commented Jan 9, 2023

#22393 (comment)

The solution presented here doesn't work properly when you have a CustomScrollView in the body of your NestedScrollView, only the MultiSliver seems to do the work.

@jong950715
Copy link

#22393 (comment)

It works for my case.
headerSliverBuilder of NestedScrollView has one floating appbar, one pinned appbar

and body has CustomScrollview, it has 2 SliverOverlapInjector.

It works properly even with CustomScrollView in the body of NestedScrollView

@Piinks
Copy link
Contributor

Piinks commented Apr 7, 2023

Resolving #33137 (currently in progress) will resolve this as well since multiple slivers will be able to go into the group, and the group itself will be able to go into the SliverOverlapAbsorber. 👍

@Piinks Piinks added P3 Issues that are less important to the Flutter project and removed P2 Important issues not at the top of the work list labels May 30, 2023
@Piinks
Copy link
Contributor

Piinks commented Jun 8, 2023

This has been resolved by #126596. With SliverMainAxisGroup, multiple slivers can be wrapped by the group, and then the group can be provided to the SliverOverlapAbsorber. :) cc @thkim1011

@Piinks Piinks closed this as completed Jun 8, 2023
@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
c: new feature Nothing broken; request for a new capability f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels. P3 Issues that are less important to the Flutter project
Projects
Development

No branches or pull requests