mponkin / fading_edge_scrollview

Flutter library for displaying fading edges on scroll views
BSD 3-Clause "New" or "Revised" License
43 stars 30 forks source link

Hide fade if content too small to be scrollable #4

Closed Nico04 closed 4 years ago

Nico04 commented 4 years ago

It may happen that content inside the scollable is too small. In that case Flutter handle it quite well : Ripple effects are disabled along with scrolling. But the fade stays. How to hide the fade in that case ?

mponkin commented 4 years ago

Could you provide example source code and/or screenshot so I can better understand the problem?

Nico04 commented 4 years ago

Here is a small sample.

Normal, expected scenario

    return Scaffold(
      backgroundColor: Colors.grey,
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Container(
              color: Colors.red,
              width: 500,
              height: 50,
            ),

            FadingEdgeScrollView.fromSingleChildScrollView(
              gradientFractionOnEnd: 0.9,
              child: SingleChildScrollView(
                controller: controller,
                scrollDirection: Axis.horizontal,
                child: Container(
                  color: Colors.red,
                  height: 200,
                  width: 500,
                ),
              ),
            ),
          ],
        ),
      ),
    );

image

Too small to scroll, unexpected behaviour

    return Scaffold(
      backgroundColor: Colors.grey,
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Container(
              color: Colors.red,
              width: 500,
              height: 50,
            ),

            FadingEdgeScrollView.fromSingleChildScrollView(
              gradientFractionOnEnd: 0.9,
              child: SingleChildScrollView(
                controller: controller,
                scrollDirection: Axis.horizontal,
                child: Container(
                  color: Colors.red,
                  height: 200,
                  width: 100,
                ),
              ),
            ),
          ],
        ),
      ),
    );

image

In that second case, because child is only width 100, there is nothing to scroll, so it should NOT display the fade effect.

Thanks :)

dannyalbuquerque commented 4 years ago

I have the same problem, listview not scrollable because fit in the screen but fade displayed at the bottom.

dannyalbuquerque commented 4 years ago

@mponkin the problem is in fading_edge_scrollview.dart line 154 and 213.

_isScrolledToEnd is set to false by default and is changed with _onScroll but if it's not scrollable _isScrolledToEnd should be set to true in initState like _isScrolledToStart

dannyalbuquerque commented 4 years ago

@mponkin @Nico04 i used this in initState to fix the problem of fading_edgescrollview.dart: ` WidgetsBinding.instance.addPostFrameCallback(() { if (_isScrolledToEnd == null && _controller.position.maxScrollExtent == 0) { setState(() { _isScrolledToEnd = true; }); } });`

and removed isScrolledToEnd default value

bool _isScrolledToEnd;

georgeherby commented 4 years ago

@dannyalbuquerque That worked for me. Are you going to raise a PR for this? If you are not i can raise a PR on your behalf, if you don't mind?

dannyalbuquerque commented 4 years ago

@georgeherby i didn't plan to raise a pull request. You can do it, no problem.

georgeherby commented 4 years ago

I have just realised that this solution does not work if the view can be resized by the user. As currently, the code you provided does not fire unless there is a scroll event and that is not triggered if you resize the window as for example if you resize the window (i am trying on a macOS app) the facemask does not appear or disappear until I scroll.

As a nasty workaround, I put inside the build function (as this triggers on screen build) some code for sorting this probably needs to be wrapped in a checker for Desktop/web (platforms that allow dynamic views sizing)

Ideally, I would have a listener for this but i don't think there is one for application resizing.

    if (_controller.hasClients && (kIsWeb || Platform.isWindows || Platform.isLinux || Platform.isMacOS)) {
      final offset = _controller.offset;
      final maxOffset = _controller.position.maxScrollExtent;
      if (maxOffset == 0 && offset == 0) {
        // NOT SCROLLABLE
        _isScrolledToStart = true;
        _isScrolledToEnd = true;
      } else if (maxOffset == offset) {
        // SCROLLABLE BUT AT END
        _isScrolledToStart = false;
        _isScrolledToEnd = true;
      } else if (maxOffset > 0 && offset == 0) {
        // SCROLLABLE BUT AT START
        _isScrolledToStart = true;
        _isScrolledToEnd = false;
      } else {
        // SCROLL IN PROGRESS
        _isScrolledToStart = false;
        _isScrolledToEnd = false;
      }
    }
georgeherby commented 4 years ago

I have found the place to put it for screen resize :) didChangeMetrics

mponkin commented 4 years ago

PR is merged and included to inversion 1.1.2. Thanks for cooperation :)