Commit 146fc617 authored by Adam Barth's avatar Adam Barth Committed by GitHub

ScrollController should notify when its offset changes (#8768)

This change make it easier to track the position of the scroll view without
having to worry about the position object changing out from under the
controller.
parent fd510931
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/animation.dart'; import 'package:flutter/animation.dart';
import 'package:flutter/foundation.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'scroll_position.dart'; import 'scroll_position.dart';
class ScrollController { class ScrollController extends ChangeNotifier {
ScrollController({ ScrollController({
this.initialScrollOffset: 0.0, this.initialScrollOffset: 0.0,
}) { }) {
...@@ -101,6 +102,7 @@ class ScrollController { ...@@ -101,6 +102,7 @@ class ScrollController {
void attach(ScrollPosition position) { void attach(ScrollPosition position) {
assert(!_positions.contains(position)); assert(!_positions.contains(position));
_positions.add(position); _positions.add(position);
position.addListener(notifyListeners);
} }
/// Unregister the given position with this controller. /// Unregister the given position with this controller.
...@@ -109,9 +111,17 @@ class ScrollController { ...@@ -109,9 +111,17 @@ class ScrollController {
/// controller will not manipulate the given position. /// controller will not manipulate the given position.
void detach(ScrollPosition position) { void detach(ScrollPosition position) {
assert(_positions.contains(position)); assert(_positions.contains(position));
position.removeListener(notifyListeners);
_positions.remove(position); _positions.remove(position);
} }
@override
void dispose() {
for (ScrollPosition position in _positions)
position.removeListener(notifyListeners);
super.dispose();
}
static ScrollPosition createDefaultScrollPosition(ScrollPhysics physics, AbstractScrollState state, ScrollPosition oldPosition) { static ScrollPosition createDefaultScrollPosition(ScrollPhysics physics, AbstractScrollState state, ScrollPosition oldPosition) {
return new ScrollPosition( return new ScrollPosition(
physics: physics, physics: physics,
......
...@@ -230,4 +230,33 @@ void main() { ...@@ -230,4 +230,33 @@ void main() {
controller.animateTo(1.0, duration: const Duration(seconds: 1), curve: Curves.linear); controller.animateTo(1.0, duration: const Duration(seconds: 1), curve: Curves.linear);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
}); });
testWidgets('Scroll controllers notify when the position changes', (WidgetTester tester) async {
final ScrollController controller = new ScrollController();
final List<double> log = <double>[];
controller.addListener(() {
log.add(controller.offset);
});
await tester.pumpWidget(new ListView(
controller: controller,
children: kStates.map<Widget>((String state) {
return new Container(height: 200.0, child: new Text(state));
}).toList(),
));
expect(log, isEmpty);
await tester.drag(find.byType(ListView), const Offset(0.0, -250.0));
expect(log, equals(<double>[ 250.0 ]));
log.clear();
controller.dispose();
await tester.drag(find.byType(ListView), const Offset(0.0, -130.0));
expect(log, isEmpty);
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment