Skip to content

Commit c813151

Browse files
authored
Merge branch 'master' into scroll-by-wheel-speedup
2 parents 66b59b8 + c267f5e commit c813151

File tree

8 files changed

+101
-12
lines changed

8 files changed

+101
-12
lines changed

packages/scrollable_positioned_list/CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# 0.3.5
2+
* Fix extraneous animation controller declaration in 0.3.4.
3+
4+
# 0.3.4
5+
* Disposed the animation controller when disposing the scrollable list.
6+
17
# 0.3.3
28
* Fix potential crash when reading from RenderBox.size.
39

packages/scrollable_positioned_list/lib/src/scrollable_positioned_list.dart

+21-3
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ class _ScrollablePositionedListState extends State<ScrollablePositionedList>
299299
void _speedupClosureSecondary() =>
300300
_speedUpScrollListener(secondary.scrollController);
301301

302+
var _animationController;
303+
302304
@override
303305
void initState() {
304306
super.initState();
@@ -330,6 +332,7 @@ class _ScrollablePositionedListState extends State<ScrollablePositionedList>
330332
.removeListener(_updatePositions);
331333
primary.scrollController.removeListener(_speedupClosurePrimary);
332334
secondary.scrollController.removeListener(_speedupClosureSecondary);
335+
_animationController?.dispose();
333336
super.dispose();
334337
}
335338

@@ -526,9 +529,11 @@ class _ScrollablePositionedListState extends State<ScrollablePositionedList>
526529
startAnimationCallback = () {
527530
SchedulerBinding.instance.addPostFrameCallback((_) {
528531
startAnimationCallback = () {};
529-
530-
opacity.parent = _opacityAnimation(opacityAnimationWeights).animate(
531-
AnimationController(vsync: this, duration: duration)..forward());
532+
_animationController?.dispose();
533+
_animationController =
534+
AnimationController(vsync: this, duration: duration)..forward();
535+
opacity.parent = _opacityAnimation(opacityAnimationWeights)
536+
.animate(_animationController);
532537
secondary.scrollController.jumpTo(-direction *
533538
(_screenScrollCount *
534539
primary.scrollController.position.viewportDimension -
@@ -584,6 +589,19 @@ class _ScrollablePositionedListState extends State<ScrollablePositionedList>
584589
_isTransitioning = false;
585590
opacity.parent = const AlwaysStoppedAnimation<double>(0);
586591
});
592+
if (mounted) {
593+
setState(() {
594+
if (opacity.value >= 0.5) {
595+
// Secondary [ListView] is more visible than the primary; make it the
596+
// new primary.
597+
var temp = primary;
598+
primary = secondary;
599+
secondary = temp;
600+
}
601+
_isTransitioning = false;
602+
opacity.parent = const AlwaysStoppedAnimation<double>(0);
603+
});
604+
}
587605
}
588606

589607
Animatable<double> _opacityAnimation(List<double> opacityAnimationWeights) {

packages/scrollable_positioned_list/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: scrollable_positioned_list
2-
version: 0.3.3
2+
version: 0.3.5
33
description: >
44
A list with helper methods to programmatically scroll to an item.
55
homepage: https://github.com/google/flutter.widgets/tree/master/packages/scrollable_positioned_list

packages/visibility_detector/CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# CHANGELOG
22

3+
## 0.4.0+2
4+
5+
* Fix a bug for updates to render objects that have not been laid out yet.
6+
7+
## 0.4.0+1
8+
9+
* Correct Flutter SDK version dependency to 3.1.0.
10+
* Replace use of deprecated APIs in the example for compatibility with Flutter v3.1.0.
11+
312
## 0.4.0
413

514
* Refactor to avoid forcing composition in the layer/render trees.

packages/visibility_detector/example/lib/main.dart

+5-2
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,10 @@ class DemoPageCell extends StatelessWidget {
368368
alignment: Alignment.center,
369369
child: FittedBox(
370370
fit: BoxFit.scaleDown,
371-
child: Text(_cellName, style: Theme.of(context).textTheme.headline4),
371+
child: Text(
372+
_cellName,
373+
style: Theme.of(context).textTheme.headlineMedium,
374+
),
372375
),
373376
);
374377

@@ -411,7 +414,7 @@ class VisibilityReport extends StatelessWidget {
411414
@override
412415
Widget build(BuildContext context) {
413416
final headingTextStyle =
414-
Theme.of(context).textTheme.headline6!.copyWith(color: Colors.white);
417+
Theme.of(context).textTheme.titleLarge?.copyWith(color: Colors.white);
415418

416419
final heading = Container(
417420
padding: const EdgeInsets.all(_reportPadding),

packages/visibility_detector/lib/src/render_visibility_detector.dart

+17-4
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,14 @@ mixin RenderVisibilityDetectorBase on RenderObject {
140140
}
141141
bool isFirstUpdate = _updates.isEmpty;
142142
_updates[key] = () {
143-
_fireCallback(layer, bounds);
143+
if (bounds == null) {
144+
// This can happen if set onVisibilityChanged was called with a non-null
145+
// value but this render object has not been laid out. In that case,
146+
// it has no size or geometry, and we should not worry about firing
147+
// an update since it never has been visible.
148+
return;
149+
}
150+
_fireCallback(layer, bounds!);
144151
};
145152
final updateInterval = VisibilityDetectorController.instance.updateInterval;
146153
if (updateInterval == Duration.zero) {
@@ -228,7 +235,9 @@ mixin RenderVisibilityDetectorBase on RenderObject {
228235

229236
/// Used to get the bounds of the render object when it is time to update
230237
/// clients about visibility.
231-
Rect get bounds;
238+
///
239+
/// A null value means bounds are not available.
240+
Rect? get bounds;
232241

233242
Matrix4? _lastPaintTransform;
234243
Rect? _lastPaintClipBounds;
@@ -280,7 +289,7 @@ class RenderVisibilityDetector extends RenderProxyBox
280289
final Key key;
281290

282291
@override
283-
Rect get bounds => semanticBounds;
292+
Rect? get bounds => hasSize ? semanticBounds : null;
284293
}
285294

286295
/// The [RenderObject] corresponding to the [SliverVisibilityDetector] widget.
@@ -302,7 +311,11 @@ class RenderSliverVisibilityDetector extends RenderProxySliver
302311
final Key key;
303312

304313
@override
305-
Rect get bounds {
314+
Rect? get bounds {
315+
if (geometry == null) {
316+
return null;
317+
}
318+
306319
Size widgetSize;
307320
Offset widgetOffset;
308321
switch (applyGrowthDirectionToAxisDirection(

packages/visibility_detector/pubspec.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
name: visibility_detector
2-
version: 0.4.0
2+
version: 0.4.0+2
33
description: >
44
A widget that detects the visibility of its child and notifies a callback.
55
repository: https://github.com/google/flutter.widgets/tree/master/packages/visibility_detector
66

77
environment:
88
sdk: '>=2.12.0 <3.0.0'
9-
flutter: '>=2.12.0'
9+
flutter: '>=3.1.0-0'
1010

1111
dependencies:
1212
flutter:

packages/visibility_detector/test/render_visibility_detector_test.dart

+40
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,44 @@ void main() {
134134

135135
expect(detector.debugScheduleUpdateCount, 0);
136136
});
137+
138+
testWidgets('RVS can schedule an update for a RO that is not laid out',
139+
(WidgetTester tester) async {
140+
final RenderVisibilityDetector detector = RenderVisibilityDetector(
141+
key: Key('test'),
142+
onVisibilityChanged: (_) {
143+
fail('should not get called');
144+
},
145+
);
146+
147+
// Force an out of band update to get scheduled without laying out.
148+
detector.onVisibilityChanged = (_) {
149+
fail('This should also not get called');
150+
};
151+
152+
expect(detector.debugScheduleUpdateCount, 1);
153+
154+
detector.dispose();
155+
});
156+
157+
testWidgets(
158+
'RVS (Sliver) can schedule an update for a RO that is not laid out',
159+
(WidgetTester tester) async {
160+
final RenderSliverVisibilityDetector detector =
161+
RenderSliverVisibilityDetector(
162+
key: Key('test'),
163+
onVisibilityChanged: (_) {
164+
fail('should not get called');
165+
},
166+
);
167+
168+
// Force an out of band update to get scheduled without laying out.
169+
detector.onVisibilityChanged = (_) {
170+
fail('This should also not get called');
171+
};
172+
173+
expect(detector.debugScheduleUpdateCount, 1);
174+
175+
detector.dispose();
176+
});
137177
}

0 commit comments

Comments
 (0)