GithubHelp home page GithubHelp logo

idootop / nested_scroll_view_plus Goto Github PK

View Code? Open in Web Editor NEW
22.0 2.0 2.0 1.34 MB

๐Ÿ“œ An enhanced NestedScrollView with support for overscrolling for both the inner and outer scrollviews.

Home Page: https://flutter-nested-scroll-view-plus.vercel.app

License: MIT License

Kotlin 0.09% Swift 0.48% Objective-C 0.03% Dart 98.14% HTML 1.27%

nested_scroll_view_plus's Introduction

nested_scroll_view_plus

pub package

An enhanced NestedScrollView offering overscroll support for both the nested and parent scroll views, ensuring a seamless scrolling experience.

๐Ÿ”ฅ Preview

Try it online: https://flutter-nested-scroll-view-plus.vercel.app

๐Ÿ’ก Usage

Installation:

flutter pub add nested_scroll_view_plus

Example usage:

import 'package:nested_scroll_view_plus/nested_scroll_view_plus.dart';

// Step 1: Replace `NestedScrollView` with `NestedScrollViewPlus`
NestedScrollViewPlus(
  headerSliverBuilder: (context, innerScrolled) => <Widget>[
    // ... insert your header sliver widgets here
  ],
  body: CustomScrollView(
    // Step 2: [๐ŸšจIMPORTANT] Set the physics of `CustomScrollView` to `AlwaysScrollableScrollPhysics`
    physics: const BouncingScrollPhysics(
      parent: AlwaysScrollableScrollPhysics(),
    ),
    slivers: <Widget>[
      // ... insert your body sliver widgets here
    ],
  ),
);

For additional examples, please visit the scroll_master repository. It includes features such as pull-to-refresh for NestedScrollView, combined scrolling for scrollview and tabview, and more.

๐Ÿš€ Upgrade and Migration Guide

With the release of version 2.0.0, there are a few important changes that require action when upgrading from an earlier version.

For Deprecated Widgets:

If you are using OverlapAbsorberPlus or OverlapInjectorPlus in your code, follow these steps:

  • Locate any header slivers wrapped with OverlapAbsorberPlus and remove the OverlapAbsorberPlus wrapper.
  • Remove any OverlapInjectorPlus widget that was placed atop your scroll views.

For OverscrollBehavior:

Search your codebase for any instance of OverscrollType and replace it with OverscrollBehavior. This will ensure compatibility with the new naming convention.

By following these steps, you should be able to smoothly transition to version 2.0.0 without any significant issues. As always, it is recommended to test your application thoroughly after performing an upgrade to ensure that all features work as intended.

โš™๏ธ Accessing the Inner or Outer Scroll Controller

To access the inner or outer scroll controller of a NestedScrollViewPlus, you can use a GlobalKey<NestedScrollViewStatePlus> to get its state.

class _ExampleState extends State<Example> {
  // 1. Create a GlobalKey
  final GlobalKey<NestedScrollViewStatePlus> myKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return NestedScrollViewPlus(
      // 2. Set the key to NestedScrollViewStatePlus
      key: myKey,
      // ...,
    );
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      // 3. Access the inner or outer scroll controller using GlobalKey<NestedScrollViewStatePlus>
      myKey.currentState!.innerController.addListener(_handleInnerScroll);
      myKey.currentState!.outerController.addListener(_handleOuterScroll);
    });
  }

  void _handleInnerScroll() {
    final innerController = myKey.currentState!.innerController;
    if (innerController.positions.length == 1) {
      print('Scrolling inner nested scrollview: ${innerController.offset}');
    }
  }

  void _handleOuterScroll() {
    final outerController = myKey.currentState!.outerController;
    if (outerController.positions.length == 1) {
      print('Scrolling outer nested scrollview: ${outerController.offset}');
    }
  }
}

๐Ÿšฉ Preserve Scroll Positions of Inner CustomScrollViews

To preserve the scroll positions of inner CustomScrollViews, you can add a PageStorageKey to the CustomScrollView widget. Here's an example:

CustomScrollView(
  key: PageStorageKey<String>('unique-key'),
  slivers: <Widget>[
    // ...,
  ],
),

By assigning a unique key to the CustomScrollView, Flutter's PageStorage mechanism will store and restore the scroll position of the inner CustomScrollViews, allowing you to maintain the scroll positions even when the widget tree is rebuilt.

โญ•๏ธ For Older Flutter Versions

If you are using an older version of Flutter, please follow these steps to install the appropriate branch from the old git repository.

dependencies:
  custom_nested_scroll_view:
    git:
      url: https://github.com/idootop/custom_nested_scroll_view.git
      # Choose the branch based on your local Flutter version
      ref: flutter-3.7

The different branches support the following Flutter versions:

Git branch Supported flutter versions
flutter-3.7 >=3.7.0-13.0.pre
flutter-3.4 >=3.4.0-27.0.pre <3.7.0-13.0.pre
flutter-3.4-pre >=3.4.0-17.0.pre <3.4.0-27.0.pre
flutter-3.0 >=2.12.0-4.0.pre <3.4.0-17.0.pre
flutter-2.x <2.12.0-4.0.pre

For more details, please visit the old documentation for CustomNestedScrollView.

โค๏ธ Acknowledgements

nested_scroll_view_plus's People

Contributors

idootop avatar

Stargazers

 avatar dreamlin avatar 49241036 avatar Choi Young Jun avatar MohammadAminZamani.afshar avatar  avatar  avatar kiwan avatar Shujaat Ali Khan avatar Superazan avatar ZhuYilin avatar Klim avatar Kosei Akaboshi avatar  avatar Xiaobai avatar Santa Takahashi avatar Fikret ลžengรผl avatar Shin Aoyama avatar Erzhan avatar  avatar  avatar codiss avatar

Watchers

 avatar  avatar

nested_scroll_view_plus's Issues

Multi headers are misbehaving

After I changed your headerSliverBuilder to like below the error occurred:
-> Part of the text is lost

 headerSliverBuilder: (context, innerScrolled) => <Widget>[
            // use OverlapAbsorberPlus to wrap your SliverAppBar
            const OverlapAbsorberPlus(
              sliver: MySliverAppBar(),
            ),
            SliverPadding(
              padding: EdgeInsets.symmetric(horizontal: 16),
              sliver: SliverToBoxAdapter(
                child: Text(
                  'After hiking towards the roaring ocean with no idea what was ahead of us, this view opened up before our eyes.'
                  'After hiking towards the roaring ocean with no idea what was ahead of us, this view opened up before our eyes.'
                  'After hiking towards the roaring ocean with no idea what was ahead of us, this view opened up before our eyes.',
                  maxLines: 5,
                  textAlign: TextAlign.center,
                  overflow: TextOverflow.visible,
                ),
              ),
            ),
          ],

RPReplay_Final1699441144.MP4

Scrolling bug.

Hello, first of all thank you for this awesome library. When I use nested scroll view or extended nested scroll view this bug doesn't happen. I specifically use this library for stretch support but the bug is pretty annoying.

I'm trying to avoid my container from going beyond appbar. But if I swipe quickly or down and up respectively sometimes (pretty much often) content goes beyond but quickly comes back when you swipe.

NestedScrollViewPlus(
          headerSliverBuilder: (context, __) {
            return [
              SliverOverlapAbsorberPlus(
                handle: NestedScrollViewPlus.sliverOverlapAbsorberHandleFor(context),
                sliver: SliverAppBar(
                  pinned: true,
                  elevation: 0,
                  backgroundColor: Colors.purple,
                  automaticallyImplyLeading: false,
                  toolbarHeight: kMinInteractiveDimensionCupertino,
                  collapsedHeight: topPadding + measures.bottomToolbarHeight - 3,
                  expandedHeight: measures.appbarHeight,
                ),
              ),
            ];
          },
          body: body,
   );
        
Builder(builder: (context) {
            return CustomScrollView(
              physics: const BouncingScrollPhysics(
                parent: AlwaysScrollableScrollPhysics(),
              ),
              slivers: [
                SliverOverlapInjectorPlus(handle: NestedScrollViewPlus.sliverOverlapAbsorberHandleFor(context)),
                SliverToBoxAdapter(
                  child: Container(color: Colors.red, height: 100),
                ),
              ],
            );
          })

I've tried every custom physics and absorber and injector combination that you've provided but no luck. Can you help me why this happens?

Screen.Recording.2024-01-21.at.00.49.19.mov

Sync difference between NestedScrollViewPlus and CustomScrollView while scrolling.

Hello again, I hope youโ€™re doing well. Sadly, I just discovered another bug related the scroll sync which again doesn't exist in NestedScrollView. If you swipe up, sometimes (2 times of 3 swipes, especially on fast swipes) the inner scroll view scrolls a little first before the outer one starts to scroll. Let me demonstrate the issue:

NestedScrollViewPlus:

NestedScrollViewPlus.mov
NestedScrollViewPlus2.mov

NestedScrollView:

NestedScrollView.mov
NestedScrollView2.mov

This happens on all versions including: 2.0.0, 1.0.3, 1.0.2, I didn't tested on older ones. You can check yourself too:

https://github.com/fikretsengul/nsw_plus_bug

Sorry for disturbing you again, thank for reading.

flutter3.13.6 ็‰ˆๆœฌ่ฟ่กŒๆŠฅ้”™๏ผŒ ๆ‰พไธๅˆฐChangeNotifier.maybeDispatchObjectCreation๏ผŒ่ฏทๆณจๆ˜Žๅบ“็‰ˆๆœฌๅ’Œflutter็‰ˆๆœฌ็š„ๅฏนๅบ”ๅ…ณ็ณป

Running Gradle task 'assembleDebug'...
../../../.pub-cache/hosted/pub.flutter-io.cn/nested_scroll_view_plus-2.0.0/lib/src/nested_scroll_view.dart:1693:22: Error: Member not found: 'ChangeNotifier.maybeDispatchObjectCreation'.
ChangeNotifier.maybeDispatchObjectCreation(this);
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Target kernel_snapshot failed: Exception

If I use TabBarView in NestedScrollViewPlus, I cannot preserve the scroll positions.

In fact, the problem is not exactly preserving the scroll positions, but rather not being able to preserve them separately. For example:

NestedScrollViewPlus(
  key: nestedScrollViewKey,
  controller: scrollController,
  headerSliverBuilder: (context, _) {
    ...
  },
  body: child,
);

ExtendedTabBarView(
  controller: _tabController,
  cacheExtent: 2,
  children: [
    CustomScrollView(
      key: PageStorageKey<UniqueKey>(UniqueKey()),
      physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
      slivers: [
        SliverList(
          delegate: SliverChildBuilderDelegate(
            (context, index) {
              final number = index + 1;

              return Container(
                height: 50,
                color:
                    index.isEven ? CupertinoColors.lightBackgroundGray : CupertinoColors.extraLightBackgroundGray,
                alignment: Alignment.center,
                child: Text(
                  '$number',
                  style: CupertinoTheme.of(context).textTheme.textStyle,
                ),
              );
            },
            childCount: 20,
          ),
        ),
      ],
    ),
    CustomScrollView(
      key: PageStorageKey<UniqueKey>(UniqueKey()),
      physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
      slivers: [
        SliverList(
          delegate: SliverChildBuilderDelegate(
            (context, index) {
              final number = index + 1;

              return Container(
                height: 50,
                color:
                    index.isEven ? CupertinoColors.lightBackgroundGray : CupertinoColors.extraLightBackgroundGray,
                alignment: Alignment.center,
                child: Text(
                  '$number',
                  style: CupertinoTheme.of(context).textTheme.textStyle,
                ),
              );
            },
            childCount: 20,
          ),
        ),
      ],
    )
  ],
);

In this configuration (I don't want to make my sliverappbar scrollable too), scrolling one view also scrolls other view.

preserve_scroll_position.mov

Any suggestion to handle this case?

Support for multiple OverlapInjectors

The problem is as follows:

When there are multiple slivers inside the headerSliverBuilder and you try to inject both of those widget's OverlapAbsorberPlus, the following exception is thrown:

โ•โ•โ•ก EXCEPTION CAUGHT BY RENDERING LIBRARY โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
The following assertion was thrown during performLayout():
A OriginalOverlapAbsorberHandle cannot be passed to multiple OriginalRenderSliverOverlapAbsorber
objects at the same time.
'package:nested_scroll_view_plus/src/nested_scroll_view_outer.dart':
Failed assertion: line 368 pos 7: 'handle._writers == 1'

The relevant error-causing widget was:
SliverOverlapAbsorberPlus
SliverOverlapAbsorberPlus:file:///Users/fleeser/.pub-cache/hosted/pub.dev/nested_scroll_view_plus-1.0.2/lib/src/nested_scroll_view_plus.dart:156:12

When the exception was thrown, this was the stack:
#2 RenderSliverOverlapAbsorberOuter.performLayout (package:nested_scroll_view_plus/src/nested_scroll_view_outer.dart:368:7)
#3 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#4 RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:601:13)
#5 RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1554:12)
#6 RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1463:20)
#7 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#8 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#9 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#10 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#11 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#12 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#13 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#14 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#15 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#16 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#17 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#18 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#19 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#20 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#21 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#22 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#23 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#24 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#25 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#26 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#27 MultiChildLayoutDelegate.layoutChild (package:flutter/src/rendering/custom_layout.dart:173:12)
#28 _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:1062:7)
#29 MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:237:7)
#30 RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:403:14)
#31 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#32 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#33 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#34 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#35 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#36 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#37 _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1434:11)
#38 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#39 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#40 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#41 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#42 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#43 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#44 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#45 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#46 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#47 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#48 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#49 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#50 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#51 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#52 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#53 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#54 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#55 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#56 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#57 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#58 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#59 RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:3714:13)
#60 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#61 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#62 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#63 RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#64 RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#65 _RenderTheaterMixin.performLayout (package:flutter/src/widgets/overlay.dart:884:15)
#66 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:2385:7)
#67 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1025:18)
#68 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1038:15)
#69 RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:591:23)
#70 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:986:13)
#71 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:457:5)
#72 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1325:15)
#73 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1255:9)
#74 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1113:5)
#75 _invoke (dart:ui/hooks.dart:312:13)
#76 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:383:5)
#77 _drawFrame (dart:ui/hooks.dart:283:31)
(elided 2 frames from class _AssertionError)

The following RenderObject was being processed when the exception was fired: RenderSliverOverlapAbsorberOuter#67258 relayoutBoundary=up1 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE:
creator: SliverOverlapAbsorberPlus โ† OverlapAbsorberPlus-[<'profile-overlap-absorber-plus-app-bar'>]
โ† OriginalNestedScrollViewViewport โ† IgnorePointer-[GlobalKey#5c76b] โ† Semantics โ† Listener โ†
_GestureSemantics โ† RawGestureDetector-[LabeledGlobalKey#08f42] โ†
Listener โ† _ScrollableScope โ† _ScrollSemantics-[GlobalKey#35de9] โ†
NotificationListener โ† โ‹ฏ
parentData: paintOffset=Offset(0.0, 0.0) (can use size)
constraints: SliverConstraints(AxisDirection.down, GrowthDirection.forward, ScrollDirection.idle,
scrollOffset: 0.0, remainingPaintExtent: 842.0, crossAxisExtent: 430.0, crossAxisDirection:
AxisDirection.right, viewportMainAxisExtent: 842.0, remainingCacheExtent: 1092.0, cacheOrigin:
0.0)
geometry: null
handle: OriginalOverlapAbsorberHandle(null, 2 WRITERS ASSIGNED)
This RenderObject had the following child:
child: _RenderSliverPinnedPersistentHeaderForWidgets#1f375 NEEDS-LAYOUT NEEDS-PAINT
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Another exception was thrown: Null check operator used on a null value
Another exception was thrown: Null check operator used on a null value

I tried to wrap SliverMainAxisGroup around both header slivers, but the pinned effect won't work anymore. Therefore I thought the solution would be to pass different keys and use them by putting both of them into the CustomScrollView.

This is the code atm:

return Scaffold(
  body: NestedScrollViewPlus(
    headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => [
      OverlapAbsorberPlus(
        key: const Key('profile-overlap-absorber-plus-app-bar'),
        sliver: SCSliverAppBar(...)
      ),
      OverlapAbsorberPlus(
        key: const Key('profile-overlap-absorber-plus-tab-bar'),
        sliver: SCSliverTabBar(...)
      )
    ],
    body: TabBarView(
      controller: _tabController,
      children: [
        CustomScrollView(
          key: const PageStorageKey<String>('profile-events-key'),
          physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
          slivers: [
            const OverlapInjectorPlus(),
            SliverList.builder(...)
          ]
        ),
        CustomScrollView(
          key: const PageStorageKey<String>('profile-ratings-key'),
          physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
          slivers: [
            const OverlapInjectorPlus(key: Key('profile-overlap-absorber-plus-app-bar')),
            const OverlapInjectorPlus(key: Key('profile-overlap-absorber-plus-tab-bar')),
            SliverList.builder(...)
          ]
        )
      ]
    )
  )
);

What I try to achieve:
One of the Tabs should contain another pinned sliver. Currently, when removing the second OverlapAbsorberPlus and OverlapInjectorPlus again, this Widget moves under the TabBar and pins itself directly under the AppBar, because this is the only Widget inside a OverlapAbsorberPlus.

Would love to hear from you!

Bouncing not work for Cupertino

First of all thanks to trying to fix NestedScrollView ! It's a pain to use with to many issues on it.

So my problem is when I use it with a CupertinoSliverNavigationBar the equivalent of SliverAppBar the bouncing do not work.

The bouncing work on the end of the list but not on the header. So my "Title" do not animate with the scroll.

I'm using SliverList.separated inside the CustomScrollView. Maybe it's related ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.