Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
b972f872
Unverified
Commit
b972f872
authored
Aug 03, 2022
by
Kate Lovett
Committed by
GitHub
Aug 03, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Clean up ScrollbarPainter (#107179)
parent
c4aea1c3
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
180 additions
and
155 deletions
+180
-155
scrollbar.dart
packages/flutter/lib/src/widgets/scrollbar.dart
+180
-155
No files found.
packages/flutter/lib/src/widgets/scrollbar.dart
View file @
b972f872
...
...
@@ -283,6 +283,7 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
_shape
=
value
;
notifyListeners
();
}
/// The amount of space by which to inset the scrollbar's start and end, as
/// well as its side to the nearest edge, in logical pixels.
///
...
...
@@ -304,7 +305,6 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
notifyListeners
();
}
/// The preferred smallest size the scrollbar thumb can shrink to when the total
/// scrollable extent is large, the current visible viewport is small, and the
/// viewport is not overscrolled.
...
...
@@ -391,23 +391,129 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
notifyListeners
();
}
void
_debugAssertIsValidOrientation
(
ScrollbarOrientation
orientation
)
{
assert
(
(
_isVertical
&&
_isVerticalOrientation
(
orientation
))
||
(!
_isVertical
&&
!
_isVerticalOrientation
(
orientation
)),
'The given ScrollbarOrientation:
$orientation
is incompatible with the current AxisDirection:
$_lastAxisDirection
.'
// - Scrollbar Details
Rect
?
_trackRect
;
// The full painted length of the track
double
get
_trackExtent
=>
_lastMetrics
!.
viewportDimension
-
_totalTrackMainAxisOffsets
;
// The full length of the track that the thumb can travel
double
get
_traversableTrackExtent
=>
_trackExtent
-
(
2
*
mainAxisMargin
);
// Track Offsets
// The track is offset by only padding.
double
get
_totalTrackMainAxisOffsets
=>
_isVertical
?
padding
.
vertical
:
padding
.
horizontal
;
double
get
_leadingTrackMainAxisOffset
{
switch
(
_resolvedOrientation
)
{
case
ScrollbarOrientation
.
left
:
case
ScrollbarOrientation
.
right
:
return
padding
.
top
;
case
ScrollbarOrientation
.
top
:
case
ScrollbarOrientation
.
bottom
:
return
padding
.
left
;
}
}
Rect
?
_thumbRect
;
// The current scroll position + _leadingThumbMainAxisOffset
late
double
_thumbOffset
;
// The fraction visible in relation to the trversable length of the track.
late
double
_thumbExtent
;
// Thumb Offsets
// The thumb is offset by padding and margins.
double
get
_leadingThumbMainAxisOffset
{
switch
(
_resolvedOrientation
)
{
case
ScrollbarOrientation
.
left
:
case
ScrollbarOrientation
.
right
:
return
padding
.
top
+
mainAxisMargin
;
case
ScrollbarOrientation
.
top
:
case
ScrollbarOrientation
.
bottom
:
return
padding
.
left
+
mainAxisMargin
;
}
}
void
_setThumbExtent
()
{
// Thumb extent reflects fraction of content visible, as long as this
// isn't less than the absolute minimum size.
// _totalContentExtent >= viewportDimension, so (_totalContentExtent - _mainAxisPadding) > 0
final
double
fractionVisible
=
clampDouble
(
(
_lastMetrics
!.
extentInside
-
_totalTrackMainAxisOffsets
)
/
(
_totalContentExtent
-
_totalTrackMainAxisOffsets
),
0.0
,
1.0
,
);
final
double
thumbExtent
=
math
.
max
(
math
.
min
(
_traversableTrackExtent
,
minOverscrollLength
),
_traversableTrackExtent
*
fractionVisible
,
);
final
double
fractionOverscrolled
=
1.0
-
_lastMetrics
!.
extentInside
/
_lastMetrics
!.
viewportDimension
;
final
double
safeMinLength
=
math
.
min
(
minLength
,
_traversableTrackExtent
);
final
double
newMinLength
=
(
_beforeExtent
>
0
&&
_afterExtent
>
0
)
// Thumb extent is no smaller than minLength if scrolling normally.
?
safeMinLength
// User is overscrolling. Thumb extent can be less than minLength
// but no smaller than minOverscrollLength. We can't use the
// fractionVisible to produce intermediate values between minLength and
// minOverscrollLength when the user is transitioning from regular
// scrolling to overscrolling, so we instead use the percentage of the
// content that is still in the viewport to determine the size of the
// thumb. iOS behavior appears to have the thumb reach its minimum size
// with ~20% of overscroll. We map the percentage of minLength from
// [0.8, 1.0] to [0.0, 1.0], so 0% to 20% of overscroll will produce
// values for the thumb that range between minLength and the smallest
// possible value, minOverscrollLength.
:
safeMinLength
*
(
1.0
-
clampDouble
(
fractionOverscrolled
,
0.0
,
0.2
)
/
0.2
);
// The `thumbExtent` should be no greater than `trackSize`, otherwise
// the scrollbar may scroll towards the wrong direction.
_thumbExtent
=
clampDouble
(
thumbExtent
,
newMinLength
,
_traversableTrackExtent
);
}
/// Check whether given scrollbar orientation is vertical
bool
_isVerticalOrientation
(
ScrollbarOrientation
orientation
)
=>
orientation
==
ScrollbarOrientation
.
left
||
orientation
==
ScrollbarOrientation
.
right
;
// - Scrollable Details
ScrollMetrics
?
_lastMetrics
;
bool
get
_lastMetricsAreScrollable
=>
_lastMetrics
!.
minScrollExtent
!=
_lastMetrics
!.
maxScrollExtent
;
AxisDirection
?
_lastAxisDirection
;
Rect
?
_thumbRect
;
Rect
?
_trackRect
;
late
double
_thumbOffset
;
bool
get
_isVertical
=>
_lastAxisDirection
==
AxisDirection
.
down
||
_lastAxisDirection
==
AxisDirection
.
up
;
bool
get
_isReversed
=>
_lastAxisDirection
==
AxisDirection
.
up
||
_lastAxisDirection
==
AxisDirection
.
left
;
// The amount of scroll distance before and after the current position.
double
get
_beforeExtent
=>
_isReversed
?
_lastMetrics
!.
extentAfter
:
_lastMetrics
!.
extentBefore
;
double
get
_afterExtent
=>
_isReversed
?
_lastMetrics
!.
extentBefore
:
_lastMetrics
!.
extentAfter
;
// The total size of the scrollable content.
double
get
_totalContentExtent
{
return
_lastMetrics
!.
maxScrollExtent
-
_lastMetrics
!.
minScrollExtent
+
_lastMetrics
!.
viewportDimension
;
}
ScrollbarOrientation
get
_resolvedOrientation
{
if
(
scrollbarOrientation
==
null
)
{
if
(
_isVertical
)
{
return
textDirection
==
TextDirection
.
ltr
?
ScrollbarOrientation
.
right
:
ScrollbarOrientation
.
left
;
}
return
ScrollbarOrientation
.
bottom
;
}
return
scrollbarOrientation
!;
}
void
_debugAssertIsValidOrientation
(
ScrollbarOrientation
orientation
)
{
assert
(
()
{
bool
isVerticalOrientation
(
ScrollbarOrientation
orientation
)
=>
orientation
==
ScrollbarOrientation
.
left
||
orientation
==
ScrollbarOrientation
.
right
;
return
(
_isVertical
&&
isVerticalOrientation
(
orientation
))
||
(!
_isVertical
&&
!
isVerticalOrientation
(
orientation
));
}(),
'The given ScrollbarOrientation:
$orientation
is incompatible with the '
'current AxisDirection:
$_lastAxisDirection
.'
);
}
// - Updating
/// Update with new [ScrollMetrics]. If the metrics change, the scrollbar will
/// show and redraw itself based on these new metrics.
...
...
@@ -433,7 +539,6 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
if
(!
needPaint
(
oldMetrics
)
&&
!
needPaint
(
metrics
))
{
return
;
}
notifyListeners
();
}
...
...
@@ -443,6 +548,8 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
radius
=
nextRadius
;
}
// - Painting
Paint
get
_paintThumb
{
return
Paint
()
..
color
=
color
.
withOpacity
(
color
.
opacity
*
fadeoutOpacityAnimation
.
value
);
...
...
@@ -459,67 +566,50 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
..
color
=
trackColor
.
withOpacity
(
trackColor
.
opacity
*
fadeoutOpacityAnimation
.
value
);
}
void
_paintScrollbar
(
Canvas
canvas
,
Size
size
,
double
thumbExtent
,
AxisDirection
direction
)
{
void
_paintScrollbar
(
Canvas
canvas
,
Size
size
)
{
assert
(
textDirection
!=
null
,
'A TextDirection must be provided before a Scrollbar can be painted.'
,
);
final
ScrollbarOrientation
resolvedOrientation
;
if
(
scrollbarOrientation
==
null
)
{
if
(
_isVertical
)
{
resolvedOrientation
=
textDirection
==
TextDirection
.
ltr
?
ScrollbarOrientation
.
right
:
ScrollbarOrientation
.
left
;
}
else
{
resolvedOrientation
=
ScrollbarOrientation
.
bottom
;
}
}
else
{
resolvedOrientation
=
scrollbarOrientation
!;
}
final
double
x
,
y
;
final
Size
thumbSize
,
trackSize
;
final
Offset
trackOffset
,
borderStart
,
borderEnd
;
_debugAssertIsValidOrientation
(
resolvedOrientation
);
switch
(
resolvedOrientation
)
{
_debugAssertIsValidOrientation
(
_resolvedOrientation
);
switch
(
_resolvedOrientation
)
{
case
ScrollbarOrientation
.
left
:
thumbSize
=
Size
(
thickness
,
thumbExtent
);
thumbSize
=
Size
(
thickness
,
_
thumbExtent
);
trackSize
=
Size
(
thickness
+
2
*
crossAxisMargin
,
_trackExtent
);
x
=
crossAxisMargin
+
padding
.
left
;
y
=
_thumbOffset
;
trackOffset
=
Offset
(
x
-
crossAxisMargin
,
padding
.
top
);
trackOffset
=
Offset
(
x
-
crossAxisMargin
,
_leadingTrackMainAxisOffset
);
borderStart
=
trackOffset
+
Offset
(
trackSize
.
width
,
0.0
);
borderEnd
=
Offset
(
trackOffset
.
dx
+
trackSize
.
width
,
trackOffset
.
dy
+
_trackExtent
);
break
;
case
ScrollbarOrientation
.
right
:
thumbSize
=
Size
(
thickness
,
thumbExtent
);
thumbSize
=
Size
(
thickness
,
_
thumbExtent
);
trackSize
=
Size
(
thickness
+
2
*
crossAxisMargin
,
_trackExtent
);
x
=
size
.
width
-
thickness
-
crossAxisMargin
-
padding
.
right
;
y
=
_thumbOffset
;
trackOffset
=
Offset
(
x
-
crossAxisMargin
,
padding
.
top
);
trackOffset
=
Offset
(
x
-
crossAxisMargin
,
_leadingTrackMainAxisOffset
);
borderStart
=
trackOffset
;
borderEnd
=
Offset
(
trackOffset
.
dx
,
trackOffset
.
dy
+
_trackExtent
);
break
;
case
ScrollbarOrientation
.
top
:
thumbSize
=
Size
(
thumbExtent
,
thickness
);
thumbSize
=
Size
(
_
thumbExtent
,
thickness
);
trackSize
=
Size
(
_trackExtent
,
thickness
+
2
*
crossAxisMargin
);
x
=
_thumbOffset
;
y
=
crossAxisMargin
+
padding
.
top
;
trackOffset
=
Offset
(
padding
.
lef
t
,
y
-
crossAxisMargin
);
trackOffset
=
Offset
(
_leadingTrackMainAxisOffse
t
,
y
-
crossAxisMargin
);
borderStart
=
trackOffset
+
Offset
(
0.0
,
trackSize
.
height
);
borderEnd
=
Offset
(
trackOffset
.
dx
+
_trackExtent
,
trackOffset
.
dy
+
trackSize
.
height
);
break
;
case
ScrollbarOrientation
.
bottom
:
thumbSize
=
Size
(
thumbExtent
,
thickness
);
thumbSize
=
Size
(
_
thumbExtent
,
thickness
);
trackSize
=
Size
(
_trackExtent
,
thickness
+
2
*
crossAxisMargin
);
x
=
_thumbOffset
;
y
=
size
.
height
-
thickness
-
crossAxisMargin
-
padding
.
bottom
;
trackOffset
=
Offset
(
padding
.
lef
t
,
y
-
crossAxisMargin
);
trackOffset
=
Offset
(
_leadingTrackMainAxisOffse
t
,
y
-
crossAxisMargin
);
borderStart
=
trackOffset
;
borderEnd
=
Offset
(
trackOffset
.
dx
+
_trackExtent
,
trackOffset
.
dy
);
break
;
...
...
@@ -557,70 +647,33 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
}
}
double
_thumbExtent
()
{
// Thumb extent reflects fraction of content visible, as long as this
// isn't less than the absolute minimum size.
// _totalContentExtent >= viewportDimension, so (_totalContentExtent - _mainAxisPadding) > 0
final
double
fractionVisible
=
clampDouble
(
(
_lastMetrics
!.
extentInside
-
_mainAxisPadding
)
/
(
_totalContentExtent
-
_mainAxisPadding
),
0.0
,
1.0
);
final
double
thumbExtent
=
math
.
max
(
math
.
min
(
_traversableTrackExtent
,
minOverscrollLength
),
_traversableTrackExtent
*
fractionVisible
,
);
final
double
fractionOverscrolled
=
1.0
-
_lastMetrics
!.
extentInside
/
_lastMetrics
!.
viewportDimension
;
final
double
safeMinLength
=
math
.
min
(
minLength
,
_traversableTrackExtent
);
final
double
newMinLength
=
(
_beforeExtent
>
0
&&
_afterExtent
>
0
)
// Thumb extent is no smaller than minLength if scrolling normally.
?
safeMinLength
// User is overscrolling. Thumb extent can be less than minLength
// but no smaller than minOverscrollLength. We can't use the
// fractionVisible to produce intermediate values between minLength and
// minOverscrollLength when the user is transitioning from regular
// scrolling to overscrolling, so we instead use the percentage of the
// content that is still in the viewport to determine the size of the
// thumb. iOS behavior appears to have the thumb reach its minimum size
// with ~20% of overscroll. We map the percentage of minLength from
// [0.8, 1.0] to [0.0, 1.0], so 0% to 20% of overscroll will produce
// values for the thumb that range between minLength and the smallest
// possible value, minOverscrollLength.
:
safeMinLength
*
(
1.0
-
clampDouble
(
fractionOverscrolled
,
0.0
,
0.2
)
/
0.2
);
// The `thumbExtent` should be no greater than `trackSize`, otherwise
// the scrollbar may scroll towards the wrong direction.
final
double
extent
=
clampDouble
(
thumbExtent
,
newMinLength
,
_traversableTrackExtent
);
return
extent
;
}
@override
void
dispose
()
{
fadeoutOpacityAnimation
.
removeListener
(
notifyListeners
);
super
.
dispose
();
}
void
paint
(
Canvas
canvas
,
Size
size
)
{
if
(
_lastAxisDirection
==
null
||
_lastMetrics
==
null
||
_lastMetrics
!.
maxScrollExtent
<=
_lastMetrics
!.
minScrollExtent
)
{
return
;
}
// Skip painting if there's not enough space.
if
(
_traversableTrackExtent
<=
0
)
{
return
;
}
// Do not paint a scrollbar if the scroll view is infinitely long.
// TODO(Piinks): Special handling for infinite scroll views,
// https://github.com/flutter/flutter/issues/41434
if
(
_lastMetrics
!.
maxScrollExtent
.
isInfinite
)
{
return
;
}
bool
get
_isVertical
=>
_lastAxisDirection
==
AxisDirection
.
down
||
_lastAxisDirection
==
AxisDirection
.
up
;
bool
get
_isReversed
=>
_lastAxisDirection
==
AxisDirection
.
up
||
_lastAxisDirection
==
AxisDirection
.
left
;
// The amount of scroll distance before and after the current position.
double
get
_beforeExtent
=>
_isReversed
?
_lastMetrics
!.
extentAfter
:
_lastMetrics
!.
extentBefore
;
double
get
_afterExtent
=>
_isReversed
?
_lastMetrics
!.
extentBefore
:
_lastMetrics
!.
extentAfter
;
// Padding of the thumb track.
double
get
_mainAxisPadding
=>
_isVertical
?
padding
.
vertical
:
padding
.
horizontal
;
// The length of the painted track.
double
get
_trackExtent
=>
_lastMetrics
!.
viewportDimension
-
_mainAxisPadding
;
// The length of the track that is traversable by the thumb.
double
get
_traversableTrackExtent
=>
_trackExtent
-
(
2
*
mainAxisMargin
);
_setThumbExtent
();
final
double
thumbPositionOffset
=
_getScrollToTrack
(
_lastMetrics
!,
_thumbExtent
);
_thumbOffset
=
thumbPositionOffset
+
_leadingThumbMainAxisOffset
;
// The total size of the scrollable content.
double
get
_totalContentExtent
{
return
_lastMetrics
!.
maxScrollExtent
-
_lastMetrics
!.
minScrollExtent
+
_lastMetrics
!.
viewportDimension
;
return
_paintScrollbar
(
canvas
,
size
);
}
// - Scroll Position Conversion
/// Convert between a thumb track position and the corresponding scroll
/// position.
///
...
...
@@ -628,7 +681,7 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
double
getTrackToScroll
(
double
thumbOffsetLocal
)
{
assert
(
thumbOffsetLocal
!=
null
);
final
double
scrollableExtent
=
_lastMetrics
!.
maxScrollExtent
-
_lastMetrics
!.
minScrollExtent
;
final
double
thumbMovableExtent
=
_traversableTrackExtent
-
_thumbExtent
()
;
final
double
thumbMovableExtent
=
_traversableTrackExtent
-
_thumbExtent
;
return
scrollableExtent
*
thumbOffsetLocal
/
thumbMovableExtent
;
}
...
...
@@ -645,35 +698,27 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
return
(
_isReversed
?
1
-
fractionPast
:
fractionPast
)
*
(
_traversableTrackExtent
-
thumbExtent
);
}
@override
void
paint
(
Canvas
canvas
,
Size
size
)
{
if
(
_lastAxisDirection
==
null
||
_lastMetrics
==
null
||
_lastMetrics
!.
maxScrollExtent
<=
_lastMetrics
!.
minScrollExtent
)
{
return
;
}
// - Hit Testing
// Skip painting if there's not enough space.
if
(
_lastMetrics
!.
viewportDimension
<=
_mainAxisPadding
||
_traversableTrackExtent
<=
0
)
{
return
;
@override
bool
?
hitTest
(
Offset
?
position
)
{
// There is nothing painted to hit.
if
(
_thumbRect
==
null
)
{
return
null
;
}
final
double
beforePadding
=
_isVertical
?
padding
.
top
:
padding
.
left
;
final
double
thumbExtent
=
_thumbExtent
();
final
double
thumbOffsetLocal
=
_getScrollToTrack
(
_lastMetrics
!,
thumbExtent
);
_thumbOffset
=
thumbOffsetLocal
+
mainAxisMargin
+
beforePadding
;
// Do not paint a scrollbar if the scroll view is infinitely long.
// TODO(Piinks): Special handling for infinite scroll views, https://github.com/flutter/flutter/issues/41434
if
(
_lastMetrics
!.
maxScrollExtent
.
isInfinite
)
{
return
;
// Interaction disabled.
if
(
ignorePointer
// The thumb is not able to be hit when transparent.
||
fadeoutOpacityAnimation
.
value
==
0.0
// Not scrollable
||
!
_lastMetricsAreScrollable
)
{
return
false
;
}
return
_
paintScrollbar
(
canvas
,
size
,
thumbExtent
,
_lastAxisDirec
tion
!);
return
_
trackRect
!.
contains
(
posi
tion
!);
}
bool
get
_lastMetricsAreScrollable
=>
_lastMetrics
!.
minScrollExtent
!=
_lastMetrics
!.
maxScrollExtent
;
/// Same as hitTest, but includes some padding when the [PointerEvent] is
/// caused by [PointerDeviceKind.touch] to make sure that the region
/// isn't too small to be interacted with by the user.
...
...
@@ -756,28 +801,6 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
}
}
// Scrollbars are interactive.
@override
bool
?
hitTest
(
Offset
?
position
)
{
if
(
_thumbRect
==
null
)
{
return
null
;
}
if
(
ignorePointer
)
{
return
false
;
}
// The thumb is not able to be hit when transparent.
if
(
fadeoutOpacityAnimation
.
value
==
0.0
)
{
return
false
;
}
if
(!
_lastMetricsAreScrollable
)
{
return
false
;
}
return
_trackRect
!.
contains
(
position
!);
}
@override
bool
shouldRepaint
(
ScrollbarPainter
oldDelegate
)
{
// Should repaint if any properties changed.
...
...
@@ -807,6 +830,12 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
@override
String
toString
()
=>
describeIdentity
(
this
);
@override
void
dispose
()
{
fadeoutOpacityAnimation
.
removeListener
(
notifyListeners
);
super
.
dispose
();
}
}
/// An extendable base class for building scrollbars that fade in and out.
...
...
@@ -1669,7 +1698,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
case
TargetPlatform
.
iOS
:
case
TargetPlatform
.
android
:
// We can only drag the scrollbar into overscroll on mobile
// platforms, and only if the physics allow it.
// platforms, and only
then
if the physics allow it.
break
;
}
position
.
jumpTo
(
newPosition
);
...
...
@@ -1908,7 +1937,7 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
()
=>
_ThumbPressGestureRecognizer
(
debugOwner:
this
,
customPaintKey:
_scrollbarPainterKey
,
pressD
uration:
widget
.
pressDuration
,
d
uration:
widget
.
pressDuration
,
),
(
_ThumbPressGestureRecognizer
instance
)
{
instance
.
onLongPress
=
handleThumbPress
;
...
...
@@ -2074,11 +2103,8 @@ class _ThumbPressGestureRecognizer extends LongPressGestureRecognizer {
_ThumbPressGestureRecognizer
({
required
Object
super
.
debugOwner
,
required
GlobalKey
customPaintKey
,
required
Duration
pressDuration
,
})
:
_customPaintKey
=
customPaintKey
,
super
(
duration:
pressDuration
,
);
required
super
.
duration
,
})
:
_customPaintKey
=
customPaintKey
;
final
GlobalKey
_customPaintKey
;
...
...
@@ -2105,10 +2131,9 @@ class _ThumbPressGestureRecognizer extends LongPressGestureRecognizer {
// track and ignores everything else, including the thumb.
class
_TrackTapGestureRecognizer
extends
TapGestureRecognizer
{
_TrackTapGestureRecognizer
({
required
Object
debugOwner
,
required
super
.
debugOwner
,
required
GlobalKey
customPaintKey
,
})
:
_customPaintKey
=
customPaintKey
,
super
(
debugOwner:
debugOwner
);
})
:
_customPaintKey
=
customPaintKey
;
final
GlobalKey
_customPaintKey
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment