Exposed optional scrollController property in ReorderableListView (#49148)
This commit is contained in:
parent
e002698c35
commit
fd1062debd
@ -62,6 +62,7 @@ class ReorderableListView extends StatefulWidget {
|
||||
this.header,
|
||||
@required this.children,
|
||||
@required this.onReorder,
|
||||
this.scrollController,
|
||||
this.scrollDirection = Axis.vertical,
|
||||
this.padding,
|
||||
this.reverse = false,
|
||||
@ -87,6 +88,15 @@ class ReorderableListView extends StatefulWidget {
|
||||
/// List [children] can only drag along this [Axis].
|
||||
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].
|
||||
final EdgeInsets padding;
|
||||
|
||||
@ -140,6 +150,7 @@ class _ReorderableListViewState extends State<ReorderableListView> {
|
||||
return _ReorderableListContent(
|
||||
header: widget.header,
|
||||
children: widget.children,
|
||||
scrollController: widget.scrollController,
|
||||
scrollDirection: widget.scrollDirection,
|
||||
onReorder: widget.onReorder,
|
||||
padding: widget.padding,
|
||||
@ -165,6 +176,7 @@ class _ReorderableListContent extends StatefulWidget {
|
||||
const _ReorderableListContent({
|
||||
@required this.header,
|
||||
@required this.children,
|
||||
@required this.scrollController,
|
||||
@required this.scrollDirection,
|
||||
@required this.padding,
|
||||
@required this.onReorder,
|
||||
@ -173,6 +185,7 @@ class _ReorderableListContent extends StatefulWidget {
|
||||
|
||||
final Widget header;
|
||||
final List<Widget> children;
|
||||
final ScrollController scrollController;
|
||||
final Axis scrollDirection;
|
||||
final EdgeInsets padding;
|
||||
final ReorderCallback onReorder;
|
||||
@ -262,7 +275,7 @@ class _ReorderableListContentState extends State<_ReorderableListContent> with T
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
_scrollController = PrimaryScrollController.of(context) ?? ScrollController();
|
||||
_scrollController = widget.scrollController ?? PrimaryScrollController.of(context) ?? ScrollController();
|
||||
super.didChangeDependencies();
|
||||
}
|
||||
|
||||
|
@ -263,6 +263,65 @@ void main() {
|
||||
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 {
|
||||
final Widget reorderableList = ReorderableListView(
|
||||
children: const <Widget>[
|
||||
|
Loading…
x
Reference in New Issue
Block a user