@@ -18,7 +18,14 @@ class StretchOverscrollEffect extends StatefulWidget {
1818 this .overscrollX = 0.0 ,
1919 this .overscrollY = 0.0 ,
2020 required this .child,
21- });
21+ }) : assert (
22+ overscrollX >= - 1.0 && overscrollX <= 1.0 ,
23+ 'overscrollX must be between -1.0 and 1.0' ,
24+ ),
25+ assert (
26+ overscrollY >= - 1.0 && overscrollY <= 1.0 ,
27+ 'overscrollY must be between -1.0 and 1.0' ,
28+ );
2229
2330 /// The horizontal overscroll amount applied for stretching effect,
2431 /// and value should be between -1 and 1 inclusive.
@@ -38,12 +45,26 @@ class StretchOverscrollEffect extends StatefulWidget {
3845class _StretchOverscrollEffectState extends State <StretchOverscrollEffect > {
3946 ui.FragmentShader ? _fragmentShader;
4047
48+ /// The maximum scale multiplier applied during a stretch effect.
49+ static const double maxStretchIntensity = 1.0 ;
50+
51+ /// The strength of the interpolation used for smoothing the effect.
52+ static const double interpolationStrength = 0.7 ;
53+
4154 @override
4255 void dispose () {
4356 _fragmentShader? .dispose ();
4457 super .dispose ();
4558 }
4659
60+ @override
61+ void initState () {
62+ super .initState ();
63+ if (! _StretchOverscrollEffectShader ._initCalled) {
64+ _StretchOverscrollEffectShader .initializeShader ();
65+ }
66+ }
67+
4768 @override
4869 Widget build (BuildContext context) {
4970 final bool isShaderNeeded =
@@ -55,26 +76,15 @@ class _StretchOverscrollEffectState extends State<StretchOverscrollEffect> {
5576 if (_StretchOverscrollEffectShader ._initialized) {
5677 _fragmentShader? .dispose ();
5778 _fragmentShader = _StretchOverscrollEffectShader ._program! .fragmentShader ();
58- _fragmentShader! .setFloat (2 , 1.0 );
79+ _fragmentShader! .setFloat (2 , maxStretchIntensity );
5980 _fragmentShader! .setFloat (3 , widget.overscrollX);
6081 _fragmentShader! .setFloat (4 , widget.overscrollY);
61- _fragmentShader! .setFloat (5 , 0.7 );
82+ _fragmentShader! .setFloat (5 , interpolationStrength );
6283
6384 imageFilter = ui.ImageFilter .shader (_fragmentShader! );
6485 } else {
65- if (! _StretchOverscrollEffectShader ._initCalled) {
66- _StretchOverscrollEffectShader .initializeShader ();
67- _StretchOverscrollEffectShader .addListener (() {
68- if (mounted) {
69- setState (() {
70- // Rebuilds the widget once the fragment shader is fully initialized.
71- });
72- }
73- });
74- } else {
75- _fragmentShader? .dispose ();
76- _fragmentShader = null ;
77- }
86+ _fragmentShader? .dispose ();
87+ _fragmentShader = null ;
7888
7989 imageFilter = ui.ImageFilter .matrix (Matrix4 .identity ().storage);
8090 }
@@ -120,7 +130,6 @@ class _StretchOverscrollEffectShader {
120130 static bool _initCalled = false ;
121131 static bool _initialized = false ;
122132 static ui.FragmentProgram ? _program;
123- static final List <VoidCallback > _listeners = < VoidCallback > [];
124133
125134 static void initializeShader () {
126135 if (! _initCalled) {
@@ -129,21 +138,8 @@ class _StretchOverscrollEffectShader {
129138 ) {
130139 _program = program;
131140 _initialized = true ;
132- _notifyListeners ();
133- _listeners.clear ();
134141 });
135142 _initCalled = true ;
136143 }
137144 }
138-
139- static void addListener (VoidCallback listener) {
140- assert (! _listeners.contains (listener));
141- _listeners.add (listener);
142- }
143-
144- static void _notifyListeners () {
145- for (final VoidCallback listener in _listeners) {
146- listener.call ();
147- }
148- }
149145}
0 commit comments