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

The inner scroll view not notify outside NestedScrollView correctly. #26409

Closed
jaggerwang opened this issue Jan 11, 2019 · 9 comments
Closed
Labels
f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.

Comments

@jaggerwang
Copy link

Problem

The inner scroll view do notify outside NestedScrollView in the first, but when load more data, it's not. It seems ScrollPosition.maxScrollExtent not change when load more data, I don't know if this is the reason.

Code

import 'package:flutter/material.dart';

import '../../components/components.dart';

class SilverAppBarScrollPage extends StatelessWidget {
  static final _tabs = ['Tab1', 'Tab2', 'Tab3'];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: JWFDDrawer(),
      body: DefaultTabController(
        length: _tabs.length,
        child: _Body(
          tabs: _tabs,
        ),
      ),
    );
  }
}

class _Body extends StatefulWidget {
  final List<String> tabs;

  _Body({
    Key key,
    @required this.tabs,
  }) : super(key: key);

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

class _BodyState extends State<_Body> {
  final _items = {
    'Tab1': <String>[],
    'Tab2': <String>[],
    'Tab3': <String>[],
  };
  final _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();

    _scrollController.addListener(_scrollListener);

    _loadItems(widget.tabs[0]);
  }

  @override
  void dispose() {
    _scrollController.removeListener(_scrollListener);

    super.dispose();
  }

  void _scrollListener() {
    print(
        'scroll position: ${_scrollController.position.pixels} ${_scrollController.position.maxScrollExtent}');
    final index = DefaultTabController.of(context).index;
    if (_scrollController.position.pixels ==
        _scrollController.position.maxScrollExtent) {
      _loadItems(widget.tabs[index]);
    }
  }

  void _loadItems(String name) {
    print('load items for $name');
    setState(() {
      final start = _items[name].length;
      _items[name]
          .addAll(List<String>.generate(20, (i) => 'Item ${start + i}'));
      print(_items[name]);
    });
  }

  Widget _buildSilverAppBar(BuildContext context, bool innerBoxIsScrolled) {
    return SliverOverlapAbsorber(
      handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
      child: SliverAppBar(
        title: const Text('Silver App Bar'),
        expandedHeight: 150,
        forceElevated: innerBoxIsScrolled,
        bottom: TabBar(
          tabs: widget.tabs.map((String name) => Tab(text: name)).toList(),
        ),
      ),
    );
  }

  Widget _buildTabBarView() {
    return TabBarView(
      children: widget.tabs.map<Widget>((name) {
        return SafeArea(
          top: false,
          bottom: false,
          child: Builder(
            builder: (context) => CustomScrollView(
                  key: PageStorageKey<String>(name),
                  slivers: <Widget>[
                    SliverOverlapInjector(
                      handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
                          context),
                    ),
                    SliverList(
                      delegate: SliverChildBuilderDelegate(
                        (context, index) =>
                            ListTile(title: Text('$name Item $index')),
                        childCount: _items[name].length,
                      ),
                    ),
                  ],
                ),
          ),
        );
      }).toList(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return NestedScrollView(
      controller: _scrollController,
      headerSliverBuilder: (context, innerBoxIsScrolled) => <Widget>[
            _buildSilverAppBar(context, innerBoxIsScrolled),
          ],
      body: _buildTabBarView(),
    );
  }
}

class JWApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'JW Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blueGrey,
      ),
      home: SilverAppBarScrollPage(),
    );
  }
}

void main() => runApp(JWApp());

Console log

I/flutter (13294): load items for Tab1
I/flutter (13294): [Item 0, Item 1, Item 2, Item 3, Item 4, Item 5, Item 6, Item 7, Item 8, Item 9, Item 10, Item 11, Item 12, Item 13, Item 14, Item 15, Item 16, Item 17, Item 18, Item 19]
I/flutter (13294): scroll position: 19.48480224609375 175.0
I/flutter (13294): scroll position: 32.47467041015625 175.0
I/flutter (13294): scroll position: 51.4598388671875 175.0
I/flutter (13294): scroll position: 74.44186401367188 175.0
I/flutter (13294): scroll position: 100.92117309570312 175.0
I/flutter (13294): scroll position: 129.8985595703125 175.0
I/flutter (13294): scroll position: 170.86654663085938 175.0
I/flutter (13294): scroll position: 175.0 175.0
I/flutter (13294): load items for Tab1
I/flutter (13294): [Item 0, Item 1, Item 2, Item 3, Item 4, Item 5, Item 6, Item 7, Item 8, Item 9, Item 10, Item 11, Item 12, Item 13, Item 14, Item 15, Item 16, Item 17, Item 18, Item 19, Item 20, Item 21, Item 22, Item 23, Item 24, Item 25, Item 26, Item 27, Item 28, Item 29, Item 30, Item 31, Item 32, Item 33, Item 34, Item 35, Item 36, Item 37, Item 38, Item 39]

Env

✗ flutter doctor -v
[✓] Flutter (Channel stable, v1.0.0, on Mac OS X 10.14.1 18B75, locale zh-Hans-CN)
    • Flutter version 1.0.0 at /Users/jagger/flutter
    • Framework revision 5391447fae (6 周前), 2018-11-29 19:41:26 -0800Engine revision 7375a0f414
    • Dart version 2.1.0 (build 2.1.0-dev.9.4 f9ebf21297)

[✓] Android toolchain - develop for Android devices (Android SDK 28.0.3)
    • Android SDK at /Users/jagger/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3ANDROID_HOME = /Users/jagger/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)
    • All Android licenses accepted.

[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
    • Xcode at /Applications/Xcode.app/Contents/DeveloperXcode 10.1, Build version 10B61
    • ios-deploy 1.9.4CocoaPods version 1.5.3

[✓] Android Studio (version 3.2)
    • Android Studio at /Applications/Android Studio.app/ContentsFlutter plugin version 31.0.1Dart plugin version 181.5656Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)

[✓] VS Code (version 1.30.2)
    • VS Code at /Applications/Visual Studio Code.app/ContentsFlutter extension version 2.21.1

[✓] Connected device (1 available)
    • Redmi 3S • 303352e7d330 • android-arm64 • Android 6.0.1 (API 23)

• No issues found!
@zoechi
Copy link
Contributor

zoechi commented Jan 11, 2019

Sounds similar to #18099

@zoechi zoechi added framework flutter/packages/flutter repository. See also f: labels. f: scrolling Viewports, list views, slivers, etc. labels Jan 11, 2019
@zoechi zoechi added this to the Goals milestone Jan 11, 2019
@skysukai
Copy link

skysukai commented Apr 4, 2019

I've met the same question.In my app, I want load more in a gridview. But if I set a ScrollController to gridview to judge if it scroll to bottom, the flexibleSpace cannot to be collapsed. Emmm, any suggestions? Here is the design:
他人信息
作品 - 滑动后

@olaide-ekolere
Copy link

I am having same issue with my gridview too because of the scrolllistener

@olaide-ekolere
Copy link

olaide-ekolere commented Jul 20, 2019

@skysukai i have resolved this by passing a ScrollController to the NestedScrollView and then listen to it for the loading more for my GridView and its fine. So i injected the ScrollController into the Widget containing the GridView and added the listener there.

@olaide-ekolere
Copy link

@skysukai Well the above broke the logic of the load more so i had to implement it another way.

@IkhwanSI13
Copy link

Solved with SingleChildScrollView.

https://gist.github.com/IkhwanSI13/eb09a588096db4c88f96ad9f2faf91d1

@debasmitasarkar
Copy link

The issue is still there

@Martibis
Copy link

I have solved this issue with wrapping the inner ListView inside a NotificationListener and listening to OverScrollNotification on that. Hope it helps someone.

@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 Aug 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

No branches or pull requests

7 participants