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

Unexpected behaviour of SliverAppBar in NestedScrollView on Mouse Scroll #55362

Closed
RoyARG02 opened this issue Apr 22, 2020 · 5 comments
Closed

Unexpected behaviour of SliverAppBar in NestedScrollView on Mouse Scroll #55362

RoyARG02 opened this issue Apr 22, 2020 · 5 comments

Comments

@RoyARG02
Copy link
Contributor

@RoyARG02 RoyARG02 commented Apr 22, 2020

I'm attempting to build a webpage using NestedScrollView. But I'm encountering various issues when scrolling by mouse wheel:

  • SliverAppBar instantly collapses (pinned: true) or disappears (floating: true) on single mouse scroll tick.
  • floating: true does not "float" the SliverAppBar, even after setting snap: true, unlike #17518.
  • Keeping SliverOverlapAbsorber/SliverOverlapInjector never collapses SliverAppBar when pinned and floating are both set to true (Removing it fixes this issue).

Except for the last issue and #17518, the above-mentioned issues are not exhibited when mouse hold-and-drag is used to scroll the NestedScrollView.

Steps to Reproduce

  1. Run flutter create bug.
  2. Update main.dart as follows: ...
import 'dart:math' as math;

import 'package:flutter/material.dart';

var rnd = math.Random(602);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (context, isInnerBoxScrolled) {
          return [
            SliverOverlapAbsorber(
              handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
              sliver: SliverAppBar(
                pinned: true,
                // floating: true,
                // snap: true,
                expandedHeight: 500.0,
                flexibleSpace: FlexibleSpaceBar(
                  title: Text(widget.title),
                ),
              ),
            ),
          ];
        },
        body: Builder(
          builder: (context) {
            return CustomScrollView(
              slivers: [
                SliverOverlapInjector(
                  handle:
                      NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                ),
                SliverFixedExtentList(
                  delegate: SliverChildBuilderDelegate(
                    (context, index) {
                      return Container(
                        color: Colors
                            .primaries[rnd.nextInt(Colors.primaries.length)],
                        alignment: Alignment.center,
                        child: Text('Element $index'),
                      );
                    },
                    childCount: 40,
                  ),
                  itemExtent: 200.0,
                ),
              ],
            );
          },
        ),
      ),
    );
  }
}
Logs
[  +25 ms] executing: [/home/anurag/flutter_master/] git -c log.showSignature=false log -n 1 --pretty=format:%H
[  +80 ms] Exit code 0 from: git -c log.showSignature=false log -n 1 --pretty=format:%H
[        ] f35b673f2b7ea7800c97d9ec096153fcca6091f2
[   +1 ms] executing: [/home/anurag/flutter_master/] git describe --match *.*.* --first-parent --long --tags
[  +35 ms] Exit code 0 from: git describe --match *.*.* --first-parent --long --tags
[        ] 1.18.0-dev.5.0-82-gf35b673f2
[  +33 ms] executing: [/home/anurag/flutter_master/] git rev-parse --abbrev-ref --symbolic @{u}
[  +12 ms] Exit code 0 from: git rev-parse --abbrev-ref --symbolic @{u}
[        ] origin/master
[        ] executing: [/home/anurag/flutter_master/] git ls-remote --get-url origin
[  +13 ms] Exit code 0 from: git ls-remote --get-url origin
[        ] https://github.com/flutter/flutter.git
[ +122 ms] executing: [/home/anurag/flutter_master/] git rev-parse --abbrev-ref HEAD
[  +17 ms] Exit code 0 from: git rev-parse --abbrev-ref HEAD
[        ] master
[ +156 ms] Artifact Instance of 'AndroidMavenArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'AndroidGenSnapshotArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'AndroidInternalBuildArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'IOSEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterWebSdk' is not required, skipping update.
[   +8 ms] Artifact Instance of 'WindowsEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerDebugSymbols' is not required, skipping update.
[  +44 ms] executing: /home/anurag/Android/Sdk/platform-tools/adb devices -l
[ +154 ms] List of devices attached
                    192.168.31.70:5555     device product:aosp_tissot model:Mi_A1 device:tissot transport_id:1
[  +19 ms] Artifact Instance of 'AndroidMavenArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'AndroidGenSnapshotArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'AndroidInternalBuildArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'IOSEngineArtifacts' is not required, skipping update.
[   +6 ms] Artifact Instance of 'WindowsEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerDebugSymbols' is not required, skipping update.
[ +504 ms] Generating
/media/D/AndroidStudioProjects/snap_on_scroll/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistran
t.java
[ +328 ms] Launching lib/main.dart on Chrome in debug mode...
[ +201 ms] Updating assets
[ +210 ms] Syncing files to device Chrome...
[ +141 ms] Generating
/media/D/AndroidStudioProjects/snap_on_scroll/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistran
t.java
[ +105 ms] <- reset
[  +20 ms] /home/anurag/flutter_master/bin/cache/dart-sdk/bin/dart
/home/anurag/flutter_master/bin/cache/artifacts/engine/linux-x64/frontend_server.dart.snapshot --sdk-root
/home/anurag/flutter_master/bin/cache/flutter_web_sdk/ --incremental --target=dartdevc --debugger-module-names
-Ddart.developer.causal_async_stacks=true --output-dill /tmp/flutter_tool.RSGRGE/app.dill --libraries-spec
file:///home/anurag/flutter_master/bin/cache/flutter_web_sdk/libraries.json --packages
/media/D/AndroidStudioProjects/snap_on_scroll/.packages -Ddart.vm.profile=false -Ddart.vm.product=false
--bytecode-options=source-positions,local-var-info,debugger-stops,instance-field-initializers,keep-unreachable-code
,avoid-closure-call-instructions --enable-asserts --track-widget-creation --filesystem-root
/tmp/flutter_tools.REABWD --filesystem-scheme org-dartlang-app --initialize-from-dill build/cache.dill --platform
file:///home/anurag/flutter_master/bin/cache/flutter_web_sdk/kernel/flutter_ddc_sdk.dill
[  +19 ms] <- compile org-dartlang-app:///web_entrypoint.dart
[+27336 ms] Syncing files to device Chrome... (completed in 27,602ms, longer than expected)
[   +2 ms] Synced 21.6MB.
[   +1 ms] <- accept
[ +508 ms] [CHROME]:
[   +1 ms] [CHROME]:DevTools listening on
ws://127.0.0.1:38443/devtools/browser/80ca58d1-ecf2-4800-ab22-6679a6d28d3d
[+5565 ms] Debug service listening on ws://127.0.0.1:42357/YvfFBa7bUgE=

[+1537 ms] Debug service listening on ws://127.0.0.1:42357/YvfFBa7bUgE=
[   +3 ms] Warning: Flutter's support for web development is not stable yet and hasn't
[        ] been thoroughly tested in production environments.
[        ] For more information see https://flutter.dev/web
[   +3 ms] 🔥  To hot restart changes while running, press "r". To hot restart (and refresh the browser), press
"R".
[   +3 ms] For a more detailed help message, press "h". To quit, press "q".

[✓] Flutter (Channel master, v1.18.0-6.0.pre.82, on Linux, locale en_US.UTF-8)
    • Flutter version 1.18.0-6.0.pre.82 at /home/anurag/flutter_master
    • Framework revision f35b673f2b (3 days ago), 2020-04-19 02:45:01 +0530
    • Engine revision a5e0b2f2f2
    • Dart version 2.9.0 (build 2.9.0-1.0.dev 5b19445d9c)

 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at /home/anurag/Android/Sdk
    • Platform android-29, build-tools 29.0.3
    • ANDROID_HOME = /home/anurag/Android/Sdk
    • Java binary at: /snap/android-studio/88/android-studio/jre/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
    • All Android licenses accepted.

[✓] Chrome - develop for the web
    • CHROME_EXECUTABLE = /opt/brave.com/brave/brave

[✓] Linux toolchain - develop for Linux desktop
    • clang++ 6.0.0
    • GNU Make 4.1

[✓] Android Studio (version 3.6)
    • Android Studio at /snap/android-studio/88/android-studio
    • Flutter plugin version 45.1.1
    • Dart plugin version 192.7761
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)

 
[✓] Connected device (4 available)            
    • Mi A1      • 192.168.31.70:5555 • android-arm64  • Android 10 (API 29)
    • Linux      • Linux              • linux-x64      • Linux
    • Chrome     • chrome             • web-javascript • Brave Browser 81.1.7.98 unknown
    • Web Server • web-server         • web-javascript • Flutter Tools

• No issues found!
@yjbanov
Copy link
Contributor

@yjbanov yjbanov commented Apr 30, 2020

This may need more triage. It is not clear if this is a web-only issue or if it affects desktop as well.

@Hixie
Copy link
Contributor

@Hixie Hixie commented May 19, 2020

Seems unlikely to be Web-specific so I'm removing that label for now; let's add it back if it doesn't repro on other platforms.

@kf6gpe kf6gpe added the P3 label May 29, 2020
@kf6gpe kf6gpe removed this from the [DEPRECATED] Near-term Goals milestone Jul 7, 2020
@Hixie Hixie removed this from the None milestone Aug 17, 2020
@Piinks Piinks changed the title [Web] Unexpected behaviour of SliverAppBar in NestedScrollView on Mouse Scroll Unexpected behaviour of SliverAppBar in NestedScrollView on Mouse Scroll Aug 20, 2020
@tomasbaran
Copy link

@tomasbaran tomasbaran commented Aug 21, 2020

may be related: #64266

@Piinks
Copy link
Contributor

@Piinks Piinks commented Sep 28, 2020

Hi @RoyARG02

  • floating: true does not "float" the SliverAppBar, even after setting snap: true, unlike #17518.

This has been fixed with NestedScrollview.floatHeaderSlivers, I don't believe this was specific to mouse scrolling


  • Keeping SliverOverlapAbsorber/SliverOverlapInjector never collapses SliverAppBar when pinned and floating are both set to true (Removing it fixes this issue).

Also should be fixed outside the scope of the mouse scroll.


  • SliverAppBar instantly collapses (pinned: true) or disappears (floating: true) on single mouse scroll tick.

I have a theory about this, though I am still familiarizing myself with PointerEvents. It looks like pointer events are being received by the individual inner/outer scroll views rather than the NestedScrollView's scroll position coordinator.

When running your reproduction, if you mouse scroll on the outer scroll view, the content in the NestedScrollView.headerSliverBuilder, it will scroll as expected, until it reaches its full extent. Additional mouse scroll is not passed on to the inner scroll view.

The header glitch you mentioned happens when you mouse scroll while hovering over the inner scroll view, or the NestedScrollView.body.

When handling a pointer event, the event is sent to every HitTestTarget in the entries of the given HitTestResult. I think the inner scroll view is receiving the event and, rather than the event being handled by the nested scroll coordinator, the inner position is affected directly. According to the NestedScrollView, if the inner position's offset is > 0, then the outer position must be at its full extent, or in this case collapsed. NestedScrollView does this in order to make sure the scroll views stay in proper alignment/sync in case the scroll offset of either position is manipulated directly (rather than using the nested scroll coordinator).

Basically, the inner scroll position changes, which the NestedScrollView then tries to correct in order to match expected alignment - thus the instant change in the header. I'm going to keep looking into this and see what kind of special handling we can do for pointer events and the nested scroll view.

@RoyARG02
Copy link
Contributor Author

@RoyARG02 RoyARG02 commented Oct 4, 2020

The header glitch you mentioned happens when you mouse scroll while hovering over the inner scroll view, or the NestedScrollView.body.

Basically, the inner scroll position changes, which the NestedScrollView then tries to correct in order to match expected alignment - thus the instant change in the header.

@Piinks now that you've mentioned, the glitch happens the other way round too. Case in point, scrolling while hovering on the header to expand it makes the inner scroll jump to the beginning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

9 participants
You can’t perform that action at this time.