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

Multiple inner ScrollPositions of NestedScrollView reset when scrolling all the way to the top #165456

Closed
AhmedLSayed9 opened this issue Mar 19, 2025 · 6 comments
Labels
f: scrolling Viewports, list views, slivers, etc. found in release: 3.29 Found to occur in 3.29 found in release: 3.31 Found to occur in 3.31 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on r: duplicate Issue is closed as a duplicate of an existing issue team-framework Owned by Framework team

Comments

@AhmedLSayed9
Copy link
Contributor

Steps to reproduce

  1. Run the sample
  2. Scroll down
  3. Change Tab to Popular
  4. Scroll down
  5. Change Tab to Latest
  6. Scroll all the way to the top
  7. Check other tabs

The issue has been partially resolved by #157756.
However, as noted by @nate-thegrate in #157756 (comment), scrolling all the way to the top of the view will still reset the scroll positions.

Expected results

I expect the other tabs to maintain their scroll positions.

Actual results

Going all the way to the top will reset the other tabs' scroll positions.

Code sample

Code sample
import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(body: NewsScreen()),
    ),
  );
}

class NewsScreen extends StatelessWidget {
  const NewsScreen({super.key});

  static const List<String> _tabs = <String>['Featured', 'Popular', 'Latest'];

  static final List<Widget> _tabViews = <Widget>[
    for (final String name in _tabs)
      SafeArea(
        top: false,
        bottom: false,
        child: Builder(builder: (BuildContext context) {
          final handle = NestedScrollView.sliverOverlapAbsorberHandleFor(context);

          return NotificationListener<ScrollNotification>(
            onNotification: (ScrollNotification notification) => true,
            child: CustomScrollView(
              key: PageStorageKey<String>(name),
              slivers: <Widget>[
                SliverOverlapInjector(handle: handle),
                SliverPadding(
                  padding: const EdgeInsets.all(8.0),
                  sliver: SliverList(
                    delegate: SliverChildBuilderDelegate(
                      childCount: 30,
                      (BuildContext context, int index) => Container(
                        margin: const EdgeInsets.only(bottom: 8),
                        width: double.infinity,
                        height: 150,
                        color: const Color(0xFFB0A4C8),
                        alignment: Alignment.center,
                        child: Text(
                          '$name $index',
                          style: const TextStyle(fontWeight: FontWeight.w600),
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          );
        }),
      ),
  ];

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: _tabs.length,
      child: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => <Widget>[
          SliverOverlapAbsorber(
            handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
            sliver: SliverSafeArea(
              top: false,
              sliver: SliverAppBar(
                title: const Text('Tab Demo'),
                floating: true,
                pinned: true,
                snap: true,
                forceElevated: innerBoxIsScrolled,
                bottom: TabBar(
                  tabs: _tabs.map((String name) => Tab(text: name)).toList(),
                ),
              ),
            ),
          ),
        ],
        body: TabBarView(children: _tabViews),
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration
Screen.Recording.2025-03-19.at.5.26.49.AM.mov

Logs

No response

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.29.2, on macOS 15.2 24C101 darwin-arm64, locale en-EG) [639ms]
    • Flutter version 3.29.2 on channel stable at /Users/ahmedelsayed/.puro/envs/stable/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision c236373904 (5 days ago), 2025-03-13 16:17:06 -0400
    • Engine revision 010c8a806b
    • Dart version 3.7.0 (build 3.7.0-323.0.dev)
    • DevTools version 2.42.0

[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0) [3.8s]
    • Android SDK at /Users/ahmedelsayed/Library/Android/sdk
    • Platform android-35, build-tools 35.0.0
    • Java binary at: /Library/Java/JavaVirtualMachines/jdk-19.jdk/Contents/Home/bin/java
      This JDK is specified in your Flutter configuration.
      To change the current JDK, run: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version Java(TM) SE Runtime Environment (build 19.0.2+7-44)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 16.2) [1,257ms]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 16C5032a
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web [14ms]
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2024.2) [14ms]
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 21.0.3+-79915917-b509.11)

[✓] VS Code (version 1.98.2) [11ms]
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.106.0

[✓] Connected device (5 available) [6.5s]

[✓] Network resources [862ms]
    • All expected network resources are available.

• No issues found!
@darshankawar darshankawar added the in triage Presently being triaged by the triage team label Mar 19, 2025
@darshankawar
Copy link
Member

@AhmedLSayed9
Can you check if this is similar to #126425 ?

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Mar 19, 2025
@AhmedLSayed9
Copy link
Contributor Author

AhmedLSayed9 commented Mar 19, 2025

@AhmedLSayed9 Can you check if this is similar to #126425 ?

Nope. It's totally different.
The mentioned issue is about preserving the horizontal scroll of TabBar items.

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Mar 19, 2025
@darshankawar
Copy link
Member

I see, please check this as well to confirm if it resembles your case or not.

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Mar 20, 2025
@AhmedLSayed9
Copy link
Contributor Author

AhmedLSayed9 commented Mar 20, 2025

I see, please check this as well to confirm if it resembles your case or not.

They might be related but not exactly the same.

This issue specifically describes how scrolling all the way to the top resets all taps, even those far away (Doesn't require AutomaticKeepAliveClientMixin).

The other issue is about how scrolling in one tab causes other tabs to scroll the same distance (Requires AutomaticKeepAliveClientMixin).

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Mar 20, 2025
@darshankawar
Copy link
Member

Thanks for the update. I was able to replicate the reported behavior on latest sdk versions.

stable : 3.29.2
master : 3.31.0-1.0.pre.135

@darshankawar darshankawar added framework flutter/packages/flutter repository. See also f: labels. f: scrolling Viewports, list views, slivers, etc. has reproducible steps The issue has been confirmed reproducible and is ready to work on found in release: 3.29 Found to occur in 3.29 found in release: 3.31 Found to occur in 3.31 team-framework Owned by Framework team and removed in triage Presently being triaged by the triage team labels Mar 21, 2025
@Piinks
Copy link
Contributor

Piinks commented Mar 25, 2025

Thanks @AhmedLSayed9 the root cause here and in #159123 is the same due to the use of the primary scroll controller. I am going to close this as a dupe of that issue.

@Piinks Piinks closed this as completed Mar 25, 2025
@Piinks Piinks reopened this Mar 25, 2025
@Piinks Piinks closed this as completed Mar 25, 2025
@darshankawar darshankawar added the r: duplicate Issue is closed as a duplicate of an existing issue label Mar 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
f: scrolling Viewports, list views, slivers, etc. found in release: 3.29 Found to occur in 3.29 found in release: 3.31 Found to occur in 3.31 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on r: duplicate Issue is closed as a duplicate of an existing issue team-framework Owned by Framework team
Projects
None yet
Development

No branches or pull requests

3 participants