Unverified Commit fd1062de authored by Lamonte's avatar Lamonte Committed by GitHub

Exposed optional scrollController property in ReorderableListView (#49148)

parent e002698c
...@@ -62,6 +62,7 @@ class ReorderableListView extends StatefulWidget { ...@@ -62,6 +62,7 @@ class ReorderableListView extends StatefulWidget {
this.header, this.header,
@required this.children, @required this.children,
@required this.onReorder, @required this.onReorder,
this.scrollController,
this.scrollDirection = Axis.vertical, this.scrollDirection = Axis.vertical,
this.padding, this.padding,
this.reverse = false, this.reverse = false,
...@@ -87,6 +88,15 @@ class ReorderableListView extends StatefulWidget { ...@@ -87,6 +88,15 @@ class ReorderableListView extends StatefulWidget {
/// List [children] can only drag along this [Axis]. /// List [children] can only drag along this [Axis].
final Axis scrollDirection; final Axis scrollDirection;
/// Creates a [ScrollPosition] to manage and determine which portion
/// of the content is visible in the scroll view.
///
/// This can be used in many ways, such as setting an initial scroll offset,
/// (via [ScrollController.initialScrollOffset]), reading the current scroll position
/// (via [ScrollController.offset]), or changing it (via [ScrollController.jumpTo] or
/// [ScrollController.animateTo]).
final ScrollController scrollController;
/// The amount of space by which to inset the [children]. /// The amount of space by which to inset the [children].
final EdgeInsets padding; final EdgeInsets padding;
...@@ -140,6 +150,7 @@ class _ReorderableListViewState extends State<ReorderableListView> { ...@@ -140,6 +150,7 @@ class _ReorderableListViewState extends State<ReorderableListView> {
return _ReorderableListContent( return _ReorderableListContent(
header: widget.header, header: widget.header,
children: widget.children, children: widget.children,
scrollController: widget.scrollController,
scrollDirection: widget.scrollDirection, scrollDirection: widget.scrollDirection,
onReorder: widget.onReorder, onReorder: widget.onReorder,
padding: widget.padding, padding: widget.padding,
...@@ -165,6 +176,7 @@ class _ReorderableListContent extends StatefulWidget { ...@@ -165,6 +176,7 @@ class _ReorderableListContent extends StatefulWidget {
const _ReorderableListContent({ const _ReorderableListContent({
@required this.header, @required this.header,
@required this.children, @required this.children,
@required this.scrollController,
@required this.scrollDirection, @required this.scrollDirection,
@required this.padding, @required this.padding,
@required this.onReorder, @required this.onReorder,
...@@ -173,6 +185,7 @@ class _ReorderableListContent extends StatefulWidget { ...@@ -173,6 +185,7 @@ class _ReorderableListContent extends StatefulWidget {
final Widget header; final Widget header;
final List<Widget> children; final List<Widget> children;
final ScrollController scrollController;
final Axis scrollDirection; final Axis scrollDirection;
final EdgeInsets padding; final EdgeInsets padding;
final ReorderCallback onReorder; final ReorderCallback onReorder;
...@@ -262,7 +275,7 @@ class _ReorderableListContentState extends State<_ReorderableListContent> with T ...@@ -262,7 +275,7 @@ class _ReorderableListContentState extends State<_ReorderableListContent> with T
@override @override
void didChangeDependencies() { void didChangeDependencies() {
_scrollController = PrimaryScrollController.of(context) ?? ScrollController(); _scrollController = widget.scrollController ?? PrimaryScrollController.of(context) ?? ScrollController();
super.didChangeDependencies(); super.didChangeDependencies();
} }
......
...@@ -263,6 +263,65 @@ void main() { ...@@ -263,6 +263,65 @@ void main() {
expect(scrollView.controller, primary2); expect(scrollView.controller, primary2);
}); });
testWidgets('Test custom ScrollController behavior when set', (WidgetTester tester) async {
const Key firstBox = Key('C');
const Key secondBox = Key('B');
const Key thirdBox = Key('A');
final ScrollController customController = ScrollController();
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: SizedBox(
height: 200,
child: ReorderableListView(
scrollController: customController,
onReorder: (int oldIndex, int newIndex) { },
children: const <Widget>[
SizedBox(width: 100.0, height: 100.0, child: Text('C'), key: firstBox),
SizedBox(width: 100.0, height: 100.0, child: Text('B'), key: secondBox),
SizedBox(width: 100.0, height: 100.0, child: Text('A'), key: thirdBox),
],
),
),
),
),
);
// Check initial scroll offset of first list item relative to
// the offset of the list view.
customController.animateTo(
40.0,
duration: const Duration(milliseconds: 200),
curve: Curves.linear
);
await tester.pumpAndSettle();
Offset listViewTopLeft = tester.getTopLeft(
find.byType(ReorderableListView),
);
Offset firstBoxTopLeft = tester.getTopLeft(
find.byKey(firstBox)
);
expect(firstBoxTopLeft.dy, listViewTopLeft.dy - 40.0);
// Drag the UI to see if the scroll controller updates accordingly
await tester.drag(
find.text('B'),
const Offset(0.0, -100.0),
);
listViewTopLeft = tester.getTopLeft(
find.byType(ReorderableListView),
);
firstBoxTopLeft = tester.getTopLeft(
find.byKey(firstBox),
);
// Initial scroll controller offset: 40.0
// Drag UI by 100.0 upwards vertically
// First 20.0 px always ignored, so scroll offset is only
// shifted by 80.0.
// Final offset: 40.0 + 80.0 = 120.0
expect(customController.offset, 120.0);
});
testWidgets('Still builds when no PrimaryScrollController is available', (WidgetTester tester) async { testWidgets('Still builds when no PrimaryScrollController is available', (WidgetTester tester) async {
final Widget reorderableList = ReorderableListView( final Widget reorderableList = ReorderableListView(
children: const <Widget>[ children: const <Widget>[
......
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