Add support for reverse to ReorderableListView (#26203)
This commit is contained in:
parent
830c0dfe83
commit
8c5a41113e
@ -41,6 +41,7 @@ class _ListDemoState extends State<ReorderableListDemo> {
|
|||||||
|
|
||||||
PersistentBottomSheetController<void> _bottomSheet;
|
PersistentBottomSheetController<void> _bottomSheet;
|
||||||
_ReorderableListType _itemType = _ReorderableListType.threeLine;
|
_ReorderableListType _itemType = _ReorderableListType.threeLine;
|
||||||
|
bool _reverse = false;
|
||||||
bool _reverseSort = false;
|
bool _reverseSort = false;
|
||||||
final List<_ListItem> _items = <String>[
|
final List<_ListItem> _items = <String>[
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
||||||
@ -51,7 +52,21 @@ class _ListDemoState extends State<ReorderableListDemo> {
|
|||||||
_itemType = type;
|
_itemType = type;
|
||||||
});
|
});
|
||||||
// Rebuild the bottom sheet to reflect the selected list view.
|
// Rebuild the bottom sheet to reflect the selected list view.
|
||||||
_bottomSheet?.setState(() { });
|
_bottomSheet?.setState(() {
|
||||||
|
// Trigger a rebuild.
|
||||||
|
});
|
||||||
|
// Close the bottom sheet to give the user a clear view of the list.
|
||||||
|
_bottomSheet?.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void changeReverse(bool newValue) {
|
||||||
|
setState(() {
|
||||||
|
_reverse = newValue;
|
||||||
|
});
|
||||||
|
// Rebuild the bottom sheet to reflect the selected list view.
|
||||||
|
_bottomSheet?.setState(() {
|
||||||
|
// Trigger a rebuild.
|
||||||
|
});
|
||||||
// Close the bottom sheet to give the user a clear view of the list.
|
// Close the bottom sheet to give the user a clear view of the list.
|
||||||
_bottomSheet?.close();
|
_bottomSheet?.close();
|
||||||
}
|
}
|
||||||
@ -67,6 +82,12 @@ class _ListDemoState extends State<ReorderableListDemo> {
|
|||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
primary: false,
|
primary: false,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
CheckboxListTile(
|
||||||
|
dense: true,
|
||||||
|
title: const Text('Reverse'),
|
||||||
|
value: _reverse,
|
||||||
|
onChanged: changeReverse,
|
||||||
|
),
|
||||||
RadioListTile<_ReorderableListType>(
|
RadioListTile<_ReorderableListType>(
|
||||||
dense: true,
|
dense: true,
|
||||||
title: const Text('Horizontal Avatars'),
|
title: const Text('Horizontal Avatars'),
|
||||||
@ -189,6 +210,7 @@ class _ListDemoState extends State<ReorderableListDemo> {
|
|||||||
child: Text('Header of the list', style: Theme.of(context).textTheme.headline))
|
child: Text('Header of the list', style: Theme.of(context).textTheme.headline))
|
||||||
: null,
|
: null,
|
||||||
onReorder: _onReorder,
|
onReorder: _onReorder,
|
||||||
|
reverse: _reverse,
|
||||||
scrollDirection: _itemType == _ReorderableListType.horizontalAvatar ? Axis.horizontal : Axis.vertical,
|
scrollDirection: _itemType == _ReorderableListType.horizontalAvatar ? Axis.horizontal : Axis.vertical,
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
children: _items.map<Widget>(buildListTile).toList(),
|
children: _items.map<Widget>(buildListTile).toList(),
|
||||||
|
@ -59,6 +59,7 @@ class ReorderableListView extends StatefulWidget {
|
|||||||
@required this.onReorder,
|
@required this.onReorder,
|
||||||
this.scrollDirection = Axis.vertical,
|
this.scrollDirection = Axis.vertical,
|
||||||
this.padding,
|
this.padding,
|
||||||
|
this.reverse = false,
|
||||||
}): assert(scrollDirection != null),
|
}): assert(scrollDirection != null),
|
||||||
assert(onReorder != null),
|
assert(onReorder != null),
|
||||||
assert(children != null),
|
assert(children != null),
|
||||||
@ -83,6 +84,20 @@ class ReorderableListView extends StatefulWidget {
|
|||||||
/// 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;
|
||||||
|
|
||||||
|
/// Whether the scroll view scrolls in the reading direction.
|
||||||
|
///
|
||||||
|
/// For example, if the reading direction is left-to-right and
|
||||||
|
/// [scrollDirection] is [Axis.horizontal], then the scroll view scrolls from
|
||||||
|
/// left to right when [reverse] is false and from right to left when
|
||||||
|
/// [reverse] is true.
|
||||||
|
///
|
||||||
|
/// Similarly, if [scrollDirection] is [Axis.vertical], then the scroll view
|
||||||
|
/// scrolls from top to bottom when [reverse] is false and from bottom to top
|
||||||
|
/// when [reverse] is true.
|
||||||
|
///
|
||||||
|
/// Defaults to false.
|
||||||
|
final bool reverse;
|
||||||
|
|
||||||
/// Called when a list child is dropped into a new position to shuffle the
|
/// Called when a list child is dropped into a new position to shuffle the
|
||||||
/// underlying list.
|
/// underlying list.
|
||||||
///
|
///
|
||||||
@ -122,6 +137,7 @@ class _ReorderableListViewState extends State<ReorderableListView> {
|
|||||||
scrollDirection: widget.scrollDirection,
|
scrollDirection: widget.scrollDirection,
|
||||||
onReorder: widget.onReorder,
|
onReorder: widget.onReorder,
|
||||||
padding: widget.padding,
|
padding: widget.padding,
|
||||||
|
reverse: widget.reverse,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -146,6 +162,7 @@ class _ReorderableListContent extends StatefulWidget {
|
|||||||
@required this.scrollDirection,
|
@required this.scrollDirection,
|
||||||
@required this.padding,
|
@required this.padding,
|
||||||
@required this.onReorder,
|
@required this.onReorder,
|
||||||
|
@required this.reverse,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Widget header;
|
final Widget header;
|
||||||
@ -153,6 +170,7 @@ class _ReorderableListContent extends StatefulWidget {
|
|||||||
final Axis scrollDirection;
|
final Axis scrollDirection;
|
||||||
final EdgeInsets padding;
|
final EdgeInsets padding;
|
||||||
final ReorderCallback onReorder;
|
final ReorderCallback onReorder;
|
||||||
|
final bool reverse;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_ReorderableListContentState createState() => _ReorderableListContentState();
|
_ReorderableListContentState createState() => _ReorderableListContentState();
|
||||||
@ -544,16 +562,25 @@ class _ReorderableListContentState extends State<_ReorderableListContent> with T
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wrappedChildren.add(_wrap(
|
if (widget.reverse) {
|
||||||
finalDropArea,
|
wrappedChildren.insert(0, _wrap(
|
||||||
widget.children.length,
|
finalDropArea,
|
||||||
constraints),
|
widget.children.length,
|
||||||
);
|
constraints),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
wrappedChildren.add(_wrap(
|
||||||
|
finalDropArea,
|
||||||
|
widget.children.length,
|
||||||
|
constraints),
|
||||||
|
);
|
||||||
|
}
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
scrollDirection: widget.scrollDirection,
|
scrollDirection: widget.scrollDirection,
|
||||||
child: _buildContainerForScrollDirection(children: wrappedChildren),
|
child: _buildContainerForScrollDirection(children: wrappedChildren),
|
||||||
padding: widget.padding,
|
padding: widget.padding,
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
|
reverse: widget.reverse,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -900,6 +900,30 @@ void main() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('ReorderableListView can be reversed', (WidgetTester tester) async {
|
||||||
|
final Widget reorderableListView = ReorderableListView(
|
||||||
|
children: const <Widget>[
|
||||||
|
SizedBox(
|
||||||
|
key: Key('A'),
|
||||||
|
child: Text('A'),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
key: Key('B'),
|
||||||
|
child: Text('B'),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
key: Key('C'),
|
||||||
|
child: Text('C'),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
reverse: true,
|
||||||
|
onReorder: (int oldIndex, int newIndex) {},
|
||||||
|
);
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
home: reorderableListView,
|
||||||
|
));
|
||||||
|
expect(tester.getCenter(find.text('A')), greaterThan(tester.getCenter(find.text('B'))));
|
||||||
|
});
|
||||||
// TODO(djshuckerow): figure out how to write a test for scrolling the list.
|
// TODO(djshuckerow): figure out how to write a test for scrolling the list.
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user