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.
This commit is contained in:
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user