diff --git a/lib/src/fading_edge_scrollview.dart b/lib/src/fading_edge_scrollview.dart index 08adb96..858c18d 100644 --- a/lib/src/fading_edge_scrollview.dart +++ b/lib/src/fading_edge_scrollview.dart @@ -171,7 +171,10 @@ class FadingEdgeScrollView extends StatefulWidget { class FadingEdgeScrollViewState extends State with WidgetsBindingObserver { late ScrollController _controller; - _ScrollState _scrollState = _ScrollState.notScrollable; + + double _offsetFromStart = 0; + double _offsetFromEnd = 0; + int lastScrollViewListLength = 0; @override @@ -202,7 +205,11 @@ class FadingEdgeScrollViewState extends State @override Widget build(BuildContext context) => ShaderMask( - shaderCallback: (bounds) => _createShaderGradient().createShader( + shaderCallback: (bounds) => _createShaderGradient( + widget.scrollDirection == Axis.vertical + ? bounds.height + : bounds.width) + .createShader( bounds.shift(Offset(-bounds.left, -bounds.top)), textDirection: Directionality.of(context), ), @@ -220,7 +227,7 @@ class FadingEdgeScrollViewState extends State ), ); - Gradient _createShaderGradient() => LinearGradient( + Gradient _createShaderGradient(double size) => LinearGradient( begin: _gradientStart, end: _gradientEnd, stops: [ @@ -229,11 +236,16 @@ class FadingEdgeScrollViewState extends State 1 - widget.gradientFractionOnEnd * 0.5, 1, ], - colors: _getColors( - widget.gradientFractionOnStart > 0 && - _scrollState.isShowGradientAtStart, - widget.gradientFractionOnEnd > 0 && - _scrollState.isShowGradientAtEnd), + colors: [ + widget.gradientFractionOnStart > 0 + ? fadeInColor(_offsetFromStart, size * widget.gradientFractionOnStart) + : Colors.white, + Colors.white, + Colors.white, + widget.gradientFractionOnEnd > 0 + ? fadeInColor(_offsetFromEnd, size * widget.gradientFractionOnEnd) + : Colors.white + ] ); AlignmentGeometry get _gradientStart => @@ -258,12 +270,16 @@ class FadingEdgeScrollViewState extends State ? AlignmentDirectional.centerStart : AlignmentDirectional.centerEnd; - List _getColors(bool showGradientAtStart, bool showGradientAtEnd) => [ - (showGradientAtStart ? Colors.transparent : Colors.white), - Colors.white, - Colors.white, - (showGradientAtEnd ? Colors.transparent : Colors.white) - ]; + Color fadeInColor(double offsetFromEdge, double threshold) { + if (offsetFromEdge <= 0) { + return Colors.white; + } + if (offsetFromEdge >= threshold) { + return Colors.transparent; + } + int alpha = 255 - (255 * offsetFromEdge / threshold).round(); + return Color.fromARGB(alpha, 255, 255, 255); + } void _updateScrollState() { if (!_controllerIsReady) { @@ -274,35 +290,13 @@ class FadingEdgeScrollViewState extends State final minOffset = _controller.positions.last.minScrollExtent; final maxOffset = _controller.positions.last.maxScrollExtent; - final isScrolledToEnd = offset >= maxOffset; - final isScrolledToStart = offset <= minOffset; - - final scrollState = switch ((isScrolledToStart, isScrolledToEnd)) { - (true, true) => _ScrollState.notScrollable, - (true, false) => _ScrollState.scrollableAtStart, - (false, true) => _ScrollState.scrollableAtEnd, - (false, false) => _ScrollState.scrollableInTheMiddle - }; - - if (_scrollState != scrollState) { + final offsetFromStart = offset - minOffset; + final offsetFromEnd = maxOffset - offset; + if (offsetFromStart != _offsetFromStart || offsetFromEnd != _offsetFromEnd) { setState(() { - _scrollState = scrollState; + _offsetFromStart = offsetFromStart; + _offsetFromEnd = offsetFromEnd; }); } } } - -enum _ScrollState { - notScrollable, - scrollableAtStart, - scrollableAtEnd, - scrollableInTheMiddle; - - bool get isShowGradientAtStart => - this == _ScrollState.scrollableAtEnd || - this == _ScrollState.scrollableInTheMiddle; - - bool get isShowGradientAtEnd => - this == _ScrollState.scrollableAtStart || - this == _ScrollState.scrollableInTheMiddle; -}