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 @@
import 'dart:async';
import 'package:flutter/animation.dart';
import 'package:flutter/foundation.dart';
import 'package:meta/meta.dart';
import 'scroll_position.dart';
class ScrollController {
class ScrollController extends ChangeNotifier {
ScrollController({
this.initialScrollOffset: 0.0,
}) {
......@@ -101,6 +102,7 @@ class ScrollController {
void attach(ScrollPosition position) {
assert(!_positions.contains(position));
_positions.add(position);
position.addListener(notifyListeners);
}
/// Unregister the given position with this controller.
......@@ -109,9 +111,17 @@ class ScrollController {
/// controller will not manipulate the given position.
void detach(ScrollPosition position) {
assert(_positions.contains(position));
position.removeListener(notifyListeners);
_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) {
return new ScrollPosition(
physics: physics,
......
......@@ -230,4 +230,33 @@ void main() {
controller.animateTo(1.0, duration: const Duration(seconds: 1), curve: Curves.linear);
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