1
+ using System ;
2
+ using Unity . UIWidgets . animation ;
3
+ using Unity . UIWidgets . async ;
4
+ using Unity . UIWidgets . foundation ;
5
+ using Unity . UIWidgets . ui ;
6
+ using Unity . UIWidgets . widgets ;
7
+
8
+ namespace Unity . UIWidgets . cupertino {
9
+ public class CupertinoScrollbarUtils {
10
+ public static Color _kScrollbarColor = new Color ( 0x99777777 ) ;
11
+ public static float _kScrollbarThickness = 2.5f ;
12
+ public static float _kScrollbarMainAxisMargin = 4.0f ;
13
+ public static float _kScrollbarCrossAxisMargin = 2.5f ;
14
+ public static float _kScrollbarMinLength = 36.0f ;
15
+ public static float _kScrollbarMinOverscrollLength = 8.0f ;
16
+ public static Radius _kScrollbarRadius = Radius . circular ( 1.25f ) ;
17
+ public static TimeSpan _kScrollbarTimeToFade = new TimeSpan ( 0 , 0 , 0 , 0 , 50 ) ;
18
+ public static TimeSpan _kScrollbarFadeDuration = new TimeSpan ( 0 , 0 , 0 , 0 , 250 ) ;
19
+ }
20
+
21
+ public class CupertinoScrollbar : StatefulWidget {
22
+ public CupertinoScrollbar (
23
+ Widget child ,
24
+ Key key = null
25
+ ) : base ( key : key ) {
26
+ this . child = child ;
27
+ }
28
+
29
+ public readonly Widget child ;
30
+
31
+ public override State createState ( ) => new _CupertinoScrollbarState ( ) ;
32
+ }
33
+
34
+ class _CupertinoScrollbarState : TickerProviderStateMixin < CupertinoScrollbar > {
35
+ ScrollbarPainter _painter ;
36
+ TextDirection _textDirection ;
37
+ AnimationController _fadeoutAnimationController ;
38
+ Animation < float > _fadeoutOpacityAnimation ;
39
+ Timer _fadeoutTimer ;
40
+
41
+ public override void initState ( ) {
42
+ base . initState ( ) ;
43
+ this . _fadeoutAnimationController = new AnimationController (
44
+ vsync : this ,
45
+ duration : CupertinoScrollbarUtils . _kScrollbarFadeDuration
46
+ ) ;
47
+ this . _fadeoutOpacityAnimation = new CurvedAnimation (
48
+ parent : this . _fadeoutAnimationController ,
49
+ curve : Curves . fastOutSlowIn
50
+ ) ;
51
+ }
52
+
53
+
54
+ public override void didChangeDependencies ( ) {
55
+ base . didChangeDependencies ( ) ;
56
+ this . _textDirection = Directionality . of ( this . context ) ;
57
+ this . _painter = this . _buildCupertinoScrollbarPainter ( ) ;
58
+ }
59
+
60
+ ScrollbarPainter _buildCupertinoScrollbarPainter ( ) {
61
+ return new ScrollbarPainter (
62
+ color : CupertinoScrollbarUtils . _kScrollbarColor ,
63
+ textDirection : this . _textDirection ,
64
+ thickness : CupertinoScrollbarUtils . _kScrollbarThickness ,
65
+ fadeoutOpacityAnimation : this . _fadeoutOpacityAnimation ,
66
+ mainAxisMargin : CupertinoScrollbarUtils . _kScrollbarMainAxisMargin ,
67
+ crossAxisMargin : CupertinoScrollbarUtils . _kScrollbarCrossAxisMargin ,
68
+ radius : CupertinoScrollbarUtils . _kScrollbarRadius ,
69
+ minLength : CupertinoScrollbarUtils . _kScrollbarMinLength ,
70
+ minOverscrollLength : CupertinoScrollbarUtils . _kScrollbarMinOverscrollLength
71
+ ) ;
72
+ }
73
+
74
+ bool _handleScrollNotification ( ScrollNotification notification ) {
75
+ if ( notification is ScrollUpdateNotification ||
76
+ notification is OverscrollNotification ) {
77
+ if ( this . _fadeoutAnimationController . status != AnimationStatus . forward ) {
78
+ this . _fadeoutAnimationController . forward ( ) ;
79
+ }
80
+
81
+ this . _fadeoutTimer ? . cancel ( ) ;
82
+ this . _painter . update ( notification . metrics , notification . metrics . axisDirection ) ;
83
+ }
84
+ else if ( notification is ScrollEndNotification ) {
85
+ this . _fadeoutTimer ? . cancel ( ) ;
86
+ this . _fadeoutTimer = Window . instance . run ( CupertinoScrollbarUtils . _kScrollbarTimeToFade , ( ) => {
87
+ this . _fadeoutAnimationController . reverse ( ) ;
88
+ this . _fadeoutTimer = null ;
89
+ } ) ;
90
+ }
91
+
92
+ return false ;
93
+ }
94
+
95
+
96
+ public override void dispose ( ) {
97
+ this . _fadeoutAnimationController . dispose ( ) ;
98
+ this . _fadeoutTimer ? . cancel ( ) ;
99
+ this . _painter . dispose ( ) ;
100
+ base . dispose ( ) ;
101
+ }
102
+
103
+
104
+ public override Widget build ( BuildContext context ) {
105
+ return new NotificationListener < ScrollNotification > (
106
+ onNotification : this . _handleScrollNotification ,
107
+ child : new RepaintBoundary (
108
+ child : new CustomPaint (
109
+ foregroundPainter : this . _painter ,
110
+ child : new RepaintBoundary (
111
+ child : this . widget . child
112
+ )
113
+ )
114
+ )
115
+ ) ;
116
+ }
117
+ }
118
+ }
0 commit comments