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
90f93a5a
Unverified
Commit
90f93a5a
authored
Dec 01, 2021
by
nt4f04uNd
Committed by
GitHub
Dec 01, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow to click through scrollbar when gestures are disabled (#91532)
parent
ee204880
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
89 additions
and
25 deletions
+89
-25
scrollbar.dart
packages/flutter/lib/src/material/scrollbar.dart
+2
-1
scrollbar.dart
packages/flutter/lib/src/widgets/scrollbar.dart
+40
-8
scrollbar_test.dart
packages/flutter/test/material/scrollbar_test.dart
+47
-16
No files found.
packages/flutter/lib/src/material/scrollbar.dart
View file @
90f93a5a
...
...
@@ -348,7 +348,8 @@ class _MaterialScrollbarState extends RawScrollbarState<_MaterialScrollbar> {
..
mainAxisMargin
=
_scrollbarTheme
.
mainAxisMargin
??
0.0
..
minLength
=
_scrollbarTheme
.
minThumbLength
??
_kScrollbarMinLength
..
padding
=
MediaQuery
.
of
(
context
).
padding
..
scrollbarOrientation
=
widget
.
scrollbarOrientation
;
..
scrollbarOrientation
=
widget
.
scrollbarOrientation
..
ignorePointer
=
!
enableGestures
;
}
@override
...
...
packages/flutter/lib/src/widgets/scrollbar.dart
View file @
90f93a5a
...
...
@@ -90,6 +90,7 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
double
minLength
=
_kMinThumbExtent
,
double
?
minOverscrollLength
,
ScrollbarOrientation
?
scrollbarOrientation
,
bool
ignorePointer
=
false
,
})
:
assert
(
color
!=
null
),
assert
(
radius
==
null
||
shape
==
null
),
assert
(
thickness
!=
null
),
...
...
@@ -102,6 +103,9 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
assert
(
minOverscrollLength
==
null
||
minOverscrollLength
>=
0
),
assert
(
padding
!=
null
),
assert
(
padding
.
isNonNegative
),
assert
(
trackColor
!=
null
),
assert
(
trackBorderColor
!=
null
),
assert
(
ignorePointer
!=
null
),
_color
=
color
,
_textDirection
=
textDirection
,
_thickness
=
thickness
,
...
...
@@ -114,7 +118,8 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
_trackColor
=
trackColor
,
_trackBorderColor
=
trackBorderColor
,
_scrollbarOrientation
=
scrollbarOrientation
,
_minOverscrollLength
=
minOverscrollLength
??
minLength
{
_minOverscrollLength
=
minOverscrollLength
??
minLength
,
_ignorePointer
=
ignorePointer
{
fadeoutOpacityAnimation
.
addListener
(
notifyListeners
);
}
...
...
@@ -341,6 +346,17 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
notifyListeners
();
}
/// Whether the painter will be ignored during hit testing.
bool
get
ignorePointer
=>
_ignorePointer
;
bool
_ignorePointer
;
set
ignorePointer
(
bool
value
)
{
if
(
ignorePointer
==
value
)
return
;
_ignorePointer
=
value
;
notifyListeners
();
}
void
_debugAssertIsValidOrientation
(
ScrollbarOrientation
orientation
)
{
assert
(
(
_isVertical
&&
_isVerticalOrientation
(
orientation
))
||
(!
_isVertical
&&
!
_isVerticalOrientation
(
orientation
)),
...
...
@@ -623,6 +639,9 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
// We have not computed the scrollbar position yet.
return
false
;
}
if
(
ignorePointer
)
{
return
false
;
}
if
(!
_lastMetricsAreScrollable
)
{
return
false
;
...
...
@@ -659,6 +678,9 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
if
(
_thumbRect
==
null
)
{
return
false
;
}
if
(
ignorePointer
)
{
return
false
;
}
// The thumb is not able to be hit when transparent.
if
(
fadeoutOpacityAnimation
.
value
==
0.0
)
{
return
false
;
...
...
@@ -688,6 +710,9 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
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
;
...
...
@@ -716,7 +741,8 @@ class ScrollbarPainter extends ChangeNotifier implements CustomPainter {
||
padding
!=
oldDelegate
.
padding
||
minLength
!=
oldDelegate
.
minLength
||
minOverscrollLength
!=
oldDelegate
.
minOverscrollLength
||
scrollbarOrientation
!=
oldDelegate
.
scrollbarOrientation
;
||
scrollbarOrientation
!=
oldDelegate
.
scrollbarOrientation
||
ignorePointer
!=
oldDelegate
.
ignorePointer
;
}
@override
...
...
@@ -1104,7 +1130,8 @@ class RawScrollbar extends StatefulWidget {
/// match native behavior. On Android, the scrollbar is not interactive by
/// default.
///
/// When false, the scrollbar will not respond to gesture or hover events.
/// When false, the scrollbar will not respond to gesture or hover events,
/// and will allow to click through it.
///
/// Defaults to true when null, unless on Android, which will default to false
/// when null.
...
...
@@ -1176,6 +1203,9 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
/// Overridable getter to indicate is gestures should be enabled on the
/// scrollbar.
///
/// When false, the scrollbar will not respond to gesture or hover events,
/// and will allow to click through it.
///
/// Subclasses can override this getter to make its value depend on an inherited
/// theme.
///
...
...
@@ -1200,14 +1230,15 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
);
scrollbarPainter
=
ScrollbarPainter
(
color:
widget
.
thumbColor
??
const
Color
(
0x66BCBCBC
),
minLength:
widget
.
minThumbLength
,
minOverscrollLength:
widget
.
minOverscrollLength
??
widget
.
minThumbLength
,
thickness:
widget
.
thickness
??
_kScrollbarThickness
,
fadeoutOpacityAnimation:
_fadeoutOpacityAnimation
,
thickness:
widget
.
thickness
??
_kScrollbarThickness
,
radius:
widget
.
radius
,
scrollbarOrientation:
widget
.
scrollbarOrientation
,
mainAxisMargin:
widget
.
mainAxisMargin
,
shape:
widget
.
shape
,
crossAxisMargin:
widget
.
crossAxisMargin
crossAxisMargin:
widget
.
crossAxisMargin
,
minLength:
widget
.
minThumbLength
,
minOverscrollLength:
widget
.
minOverscrollLength
??
widget
.
minThumbLength
,
);
}
...
...
@@ -1342,7 +1373,8 @@ class RawScrollbarState<T extends RawScrollbar> extends State<T> with TickerProv
..
shape
=
widget
.
shape
..
crossAxisMargin
=
widget
.
crossAxisMargin
..
minLength
=
widget
.
minThumbLength
..
minOverscrollLength
=
widget
.
minOverscrollLength
??
widget
.
minThumbLength
;
..
minOverscrollLength
=
widget
.
minOverscrollLength
??
widget
.
minThumbLength
..
ignorePointer
=
!
enableGestures
;
}
@override
...
...
packages/flutter/test/material/scrollbar_test.dart
View file @
90f93a5a
...
...
@@ -12,6 +12,7 @@ import 'dart:ui' as ui;
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/scheduler.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
...
...
@@ -1213,6 +1214,7 @@ void main() {
},
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
TargetPlatform
.
fuchsia
}));
testWidgets
(
'Scrollbar dragging is disabled by default on Android'
,
(
WidgetTester
tester
)
async
{
int
tapCount
=
0
;
final
ScrollController
scrollController
=
ScrollController
();
await
tester
.
pumpWidget
(
MaterialApp
(
...
...
@@ -1221,8 +1223,18 @@ void main() {
child:
Scrollbar
(
isAlwaysShown:
true
,
controller:
scrollController
,
child:
const
SingleChildScrollView
(
child:
SizedBox
(
width:
4000.0
,
height:
4000.0
),
child:
SingleChildScrollView
(
dragStartBehavior:
DragStartBehavior
.
down
,
child:
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
{
tapCount
+=
1
;
},
child:
const
SizedBox
(
width:
4000.0
,
height:
4000.0
,
),
),
),
),
),
...
...
@@ -1250,30 +1262,49 @@ void main() {
);
// Try to drag the thumb down.
const
double
scrollAmount
=
1
0.0
;
final
TestGesture
dragScrollbarThumbGesture
=
await
tester
.
startGesture
(
const
Offset
(
797.0
,
45.0
));
await
tester
.
pumpAndSettle
();
await
dragScrollbarThumbGesture
.
moveBy
(
const
Offset
(
0.0
,
scrollAmount
));
await
tester
.
pumpAndSettle
();
await
dragScrollbarThumbGesture
.
up
(
);
const
double
scrollAmount
=
5
0.0
;
await
tester
.
dragFrom
(
const
Offset
(
797.0
,
45.0
),
const
Offset
(
0.0
,
scrollAmount
),
touchSlopY:
0.0
,
);
await
tester
.
pumpAndSettle
();
// Dragging on the thumb does not change the offset.
expect
(
scrollController
.
offset
,
0.0
);
expect
(
tapCount
,
0
);
//
Drag in the track
area to validate pass through to scrollable.
final
TestGesture
dragPassThroughTrack
=
await
tester
.
startGesture
(
const
Offset
(
797.0
,
250.0
));
await
dragPassThroughTrack
.
moveBy
(
const
Offset
(
0.0
,
-
scrollAmount
));
await
tester
.
pumpAndSettle
();
await
dragPassThroughTrack
.
up
(
);
//
Try to drag up in the thumb
area to validate pass through to scrollable.
await
tester
.
dragFrom
(
const
Offset
(
797.0
,
45.0
),
const
Offset
(
0.0
,
-
scrollAmount
),
);
await
tester
.
pumpAndSettle
();
// The scroll view received the drag.
expect
(
scrollController
.
offset
,
scrollAmount
);
expect
(
tapCount
,
0
);
// Tap on the track to validate the scroll view will not page.
await
tester
.
tapAt
(
const
Offset
(
797.0
,
200.0
));
// Drag in the track area to validate pass through to scrollable.
await
tester
.
dragFrom
(
const
Offset
(
797.0
,
45.0
),
const
Offset
(
0.0
,
-
scrollAmount
),
touchSlopY:
0.0
,
);
await
tester
.
pumpAndSettle
();
// The scroll view received the drag.
expect
(
scrollController
.
offset
,
scrollAmount
*
2
);
expect
(
tapCount
,
0
);
// Tap on the thumb to validate the scroll view receives a click.
await
tester
.
tapAt
(
const
Offset
(
797.0
,
45.0
));
await
tester
.
pumpAndSettle
();
expect
(
tapCount
,
1
);
// Tap on the track to validate the scroll view will not page and receives a click.
await
tester
.
tapAt
(
const
Offset
(
797.0
,
400.0
));
await
tester
.
pumpAndSettle
();
// The offset should not have changed.
expect
(
scrollController
.
offset
,
scrollAmount
);
expect
(
scrollController
.
offset
,
scrollAmount
*
2
);
expect
(
tapCount
,
2
);
});
testWidgets
(
'Simultaneous dragging and pointer scrolling does not cause a crash'
,
(
WidgetTester
tester
)
async
{
...
...
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