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,
|
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 {
|
|||||||
/// 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> {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
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
|
|||||||
|
|
||||||
@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() {
|
|||||||
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>[
|
||||||
|
Loading…
x
Reference in New Issue
Block a user