Skip to content

The app crashes while trying to drag the Scrollbar when used along with SliverList #74404

Closed

Description

@ganeshrvel

Steps to Reproduce

The app crashes while trying to drag the Scrollbar when used along with SliverList

const itemLength = 300;

Scrollbar(
      controller: _scrollController,
      child: CustomScrollView(
        controller: _scrollController,
        physics: const ScrollPhysics(),
        slivers: <Widget>[
          SliverList(
            delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
              if (index >= itemLength) {
                return null;
              }

              return Container( width: 20);
            }),
          ),
        ],
      ),
    );

Expected results:
Scroll should work fine when scrollbar is dragged using mouse pointer

Actual results:
Screen recordings:

  1. https://drive.google.com/file/d/14xabgQXPmU_MBA4APOIfrnGfwvBXfPlq/view?usp=sharing
  2. https://drive.google.com/file/d/1PAnfumdzqZt5L4wIfLCLRgpEXe8XzRd0/view?usp=sharing
  3. https://drive.google.com/file/d/1BOKPk3K47d5oogI7GYMNpB3lsjOfSrhM/view?usp=sharing

My observation:

  1. Scrolling using trackpad doesn't break the app
  2. Dragging and scrolling the scrollbar results in app crash.
  3. A couple of times I was able to pull the scrollbar out of the app window (of course the app crashed soon after).
  4. For a list with a lot of rows the scroll bar doesn't show up until we reach the bottom (the app crashes soon after dragging the scrollbar)

Error:

flutter: �[38;5;196m│ �[0m�[39m�[48;5;196m'package:flutter/src/rendering/viewport.dart': Failed assertion: line 1522 pos 12: 'correctedOffset.isFinite': is not true.�[0m�[49m
flutter: �[38;5;196m├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄�[0m
flutter: �[38;5;196m│ #0   _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
flutter: �[38;5;196m│ #1   _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
flutter: �[38;5;196m│ #2   RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1522:12)
flutter: �[38;5;196m│ #3   RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1479:20)
flutter: �[38;5;196m│ #4   RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1634:7)
flutter: �[38;5;196m│ #5   PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:884:18)
flutter: �[38;5;196m│ #6   RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:453:19)
flutter: �[38;5;196m│ #7   WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:870:13)
flutter: �[38;5;196m

Logs
[✓] Flutter (Channel master, 1.26.0-2.0.pre.419, on macOS 11.1 20C69
    darwin-x64, locale en-GB)
[✓] Android toolchain - develop for Android devices (Android SDK version
    30.0.3)
[✓] Xcode - develop for iOS and macOS

flutter --version

Flutter 1.26.0-2.0.pre.419 • channel master • https://github.com/flutter/flutter.git
Framework • revision 913d5933c1 (89 minutes ago) • 2021-01-19 22:34:03 -0800
Engine • revision b58dbc88fc
Tools • Dart 2.12.0 (build 2.12.0-240.0.dev)

Activity

  1. LefebvreIlyas commented on Jan 21, 2021

    @LefebvreIlyas

    Hello @ganeshrvel the problem is probably in the following lines:

    if (index >= itemLength) {
        return null;
    }

    You must never return null for a widget!

    Try this code please:

    const itemLength = 300;
    
    Scrollbar(
        controller: _scrollController,
        child: CustomScrollView(
            controller: _scrollController,
            physics: const ScrollPhysics(),
            slivers: <Widget>[
                SliverList(
                    delegate: SliverChildBuilderDelegate(
                        (BuildContext context, int index) {
                            return Container( width: 20);
                        },
                        childCount: itemLength,
                    ),
                ),
            ],
        ),
    );
  2. ganeshrvel commented on Jan 21, 2021

    @ganeshrvel
    Author

    You must never return null for a widget!

    But returning null is allowed for creating infinite list in SliverList. itemLength won't be always available in such cases

  3. LefebvreIlyas commented on Jan 21, 2021

    @LefebvreIlyas

    You must never return null for a widget!

    But returning null is allowed for creating infinite list in SliverList. itemLength won't be always available in such cases

    Yes, you are right! 🤦‍♂️

    From the doc of SliverChildBuilderDelegate.builder

    Should return null if asked to build a widget with a greater index than exists.

  4. LefebvreIlyas commented on Jan 21, 2021

    @LefebvreIlyas

    If it's an infinite list what should the scrollbar look like ?

  5. added
    p: material_uimaterial_ui package in flutter/packages
    f: scrollingViewports, list views, slivers, etc.
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Jan 21, 2021
  6. HansMuller commented on Jan 21, 2021

    @HansMuller
    Contributor
  7. Piinks commented on Jan 21, 2021

    @Piinks
    Contributor

    Scrollbar does not currently support infinite scroll views. You can follow #41434 for that feature.
    Because of that, the Scrollbar should not show up if the scroll view has an infinite length, so I am curious why it is showing in your sample.

  8. Piinks commented on Jan 21, 2021

    @Piinks
    Contributor

    I think this is working as intended, since the Scrollbar is not intended to work this way currently. I was able to reproduce with this sample:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          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> {
      final itemLength = 300;
      final _scrollController = ScrollController();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Scrollbar(
            controller: _scrollController,
            child: CustomScrollView(
              controller: _scrollController,
              physics: const ScrollPhysics(),
              slivers: <Widget>[
                SliverList(
                  delegate:
                      SliverChildBuilderDelegate((BuildContext context, int index) {
                    if (index >= itemLength) {
                      return null;
                    }
                    return Container(height: 20, child: Text('Index $index'));
                  }),
                ),
              ],
            ),
          ),
        );
      }
    }

    The reason why the Scrollbar does not show until you reach the bottom is because the SliverChildBuilderDelegate does not have childCount set. So while you are scrolling down the list, the maxScrollExtent is infinity, therefore no Scrollbar is painted.

    When you reach the end of the list and the delegate returns null, then the maxScrollExtent is known and no longer infinite. That is why the Scrollbar shows up, it now has a length it can work with to calculate the right positioning, which is at the end of the list.

    When you try to drag on it at this point, scrolling back up the list, the maxScrollExtent goes to infinity again since we're no longer at the end of the list. This is what causes the crash, since you are now attempting to drag on a Scrollbar that is given infinite space to position itself in.

    I would recommend following #41434 for when we add support for infinitely scrollable scrollbars. If there is another aspect of this that is not covered by that issue, let us know and we will look into it. :) Thanks!

  9. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Jan 21, 2021
  10. ganeshrvel commented on Jan 21, 2021

    @ganeshrvel
    Author

    @Piinks Wonderfully explained! I will close this issue for now. Thanks! :)

  11. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Feb 5, 2021
  12. github-actions commented on Aug 6, 2021

    @github-actions

    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.

  13. locked as resolved and limited conversation to collaborators on Aug 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    c: crashStack traces logged to the consolef: scrollingViewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.p: material_uimaterial_ui package in flutter/packages

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions