diff --git a/lib/src/widgets/reorderable_wrap.dart b/lib/src/widgets/reorderable_wrap.dart index abc3010..c2349c0 100644 --- a/lib/src/widgets/reorderable_wrap.dart +++ b/lib/src/widgets/reorderable_wrap.dart @@ -17,8 +17,6 @@ import './typedefs.dart'; import './wrap.dart'; import './transitions.dart'; import '../rendering/wrap.dart'; -import 'reorderable_mixin.dart'; - /// Reorderable (drag and drop) version of [Wrap], A widget that displays its /// children in multiple horizontal or vertical runs. @@ -41,9 +39,9 @@ class ReorderableWrap extends StatefulWidget { Key key, this.header, this.footer, - this.controller, @required this.children, @required this.onReorder, + this.borderRadiusOnDrag, this.direction = Axis.horizontal, this.scrollDirection = Axis.vertical, this.padding, @@ -62,7 +60,7 @@ class ReorderableWrap extends StatefulWidget { this.onNoReorder, this.onReorderStarted, }) : assert(direction != null), - assert(onReorder != null), + //assert(onReorder != null), assert(children != null), // assert( // children.every((Widget w) => w.key != null), @@ -76,11 +74,6 @@ class ReorderableWrap extends StatefulWidget { final Widget header; final Widget footer; - /// A custom scroll [controller]. - /// To control the initial scroll offset of the scroll view, provide a - /// [controller] with its [ScrollController.initialScrollOffset] property set. - final ScrollController controller; - /// The widgets to display. final List children; @@ -96,6 +89,9 @@ class ReorderableWrap extends StatefulWidget { /// The amount of space by which to inset the [children]. final EdgeInsets padding; + /// BorderRadius for the elevation shadow in the background while dragging + final BorderRadiusGeometry borderRadiusOnDrag; + /// Called when a child is dropped into a new position to shuffle the /// children. final ReorderCallback onReorder; @@ -271,6 +267,7 @@ class _ReorderableWrapState extends State { children: widget.children, direction: widget.direction, scrollDirection: widget.scrollDirection, + borderRadiusOnDrag: widget.borderRadiusOnDrag, onReorder: widget.onReorder, onNoReorder: widget.onNoReorder, onReorderStarted: widget.onReorderStarted, @@ -287,7 +284,6 @@ class _ReorderableWrapState extends State { verticalDirection: widget.verticalDirection, minMainAxisCount: widget.minMainAxisCount, maxMainAxisCount: widget.maxMainAxisCount, - controller: widget.controller, ); }, ); @@ -306,38 +302,37 @@ class _ReorderableWrapState extends State { // This widget is responsible for the inside of the Overlay in the // ReorderableListView. class _ReorderableWrapContent extends StatefulWidget { - const _ReorderableWrapContent({ - this.header, - this.footer, - this.controller, - @required this.children, - @required this.direction, - @required this.scrollDirection, - @required this.padding, - @required this.onReorder, - @required this.onNoReorder, - @required this.onReorderStarted, - @required this.buildItemsContainer, - @required this.buildDraggableFeedback, - @required this.needsLongPressDraggable, - @required this.alignment, - @required this.spacing, - @required this.runAlignment, - @required this.runSpacing, - @required this.crossAxisAlignment, - @required this.textDirection, - @required this.verticalDirection, - @required this.minMainAxisCount, - @required this.maxMainAxisCount, - }); + const _ReorderableWrapContent( + {this.header, + this.footer, + @required this.children, + @required this.direction, + @required this.scrollDirection, + @required this.padding, + @required this.onReorder, + @required this.onNoReorder, + @required this.onReorderStarted, + @required this.buildItemsContainer, + @required this.buildDraggableFeedback, + @required this.needsLongPressDraggable, + @required this.alignment, + @required this.spacing, + @required this.runAlignment, + @required this.runSpacing, + @required this.crossAxisAlignment, + @required this.textDirection, + @required this.verticalDirection, + @required this.minMainAxisCount, + @required this.maxMainAxisCount, + this.borderRadiusOnDrag}); final Widget header; final Widget footer; - final ScrollController controller; final List children; final Axis direction; final Axis scrollDirection; final EdgeInsets padding; + final BorderRadiusGeometry borderRadiusOnDrag; final ReorderCallback onReorder; final NoReorderCallback onNoReorder; final ReorderStartedCallback onReorderStarted; @@ -360,7 +355,7 @@ class _ReorderableWrapContent extends StatefulWidget { } class _ReorderableWrapContentState extends State<_ReorderableWrapContent> - with TickerProviderStateMixin<_ReorderableWrapContent>, ReorderableMixin { + with TickerProviderStateMixin<_ReorderableWrapContent> { // The extent along the [widget.scrollDirection] axis to allow a child to // drop into when the user reorders list children. // @@ -465,7 +460,8 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> @override void didChangeDependencies() { - _scrollController = widget.controller ?? (PrimaryScrollController.of(context) ?? ScrollController()); + _scrollController = + PrimaryScrollController.of(context) ?? ScrollController(); super.didChangeDependencies(); } @@ -655,8 +651,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // debugPrint('_reorder: startIndex:$startIndex endIndex:$endIndex'); if (startIndex != endIndex) widget.onReorder(startIndex, endIndex); - else if (widget.onNoReorder != null) - widget.onNoReorder(startIndex); + else if (widget.onNoReorder != null) widget.onNoReorder(startIndex); // Animates leftover space in the drop area closed. // TODO(djshuckerow): bring the animation in line with the Material // specifications. @@ -700,21 +695,22 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // before index+2, which is after the space at index+1. void moveAfter() => reorder(index, index + 2); - final MaterialLocalizations localizations = MaterialLocalizations.of(context); + final MaterialLocalizations localizations = + MaterialLocalizations.of(context); if (localizations != null) { // If the item can move to before its current position in the list. if (index > 0) { semanticsActions[CustomSemanticsAction( - label: localizations.reorderItemToStart)] = moveToStart; + label: localizations.reorderItemToStart)] = moveToStart; String reorderItemBefore = localizations.reorderItemUp; if (widget.direction == Axis.horizontal) { reorderItemBefore = Directionality.of(context) == TextDirection.ltr - ? localizations.reorderItemLeft - : localizations.reorderItemRight; + ? localizations.reorderItemLeft + : localizations.reorderItemRight; } semanticsActions[CustomSemanticsAction(label: reorderItemBefore)] = - moveBefore; + moveBefore; } // If the item can move to after its current position in the list. @@ -722,14 +718,13 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> String reorderItemAfter = localizations.reorderItemDown; if (widget.direction == Axis.horizontal) { reorderItemAfter = Directionality.of(context) == TextDirection.ltr - ? localizations.reorderItemRight - : localizations.reorderItemLeft; + ? localizations.reorderItemRight + : localizations.reorderItemLeft; } semanticsActions[CustomSemanticsAction(label: reorderItemAfter)] = - moveAfter; - semanticsActions[ - CustomSemanticsAction(label: localizations.reorderItemToEnd)] = - moveToEnd; + moveAfter; + semanticsActions[CustomSemanticsAction( + label: localizations.reorderItemToEnd)] = moveToEnd; } } @@ -757,11 +752,27 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> } Widget _makeAppearingWidget(Widget child) { - return makeAppearingWidget(child, _entranceController, null, widget.direction,); + return SizeTransitionWithIntrinsicSize( + sizeFactor: _entranceController, + axis: widget.direction, + child: FadeTransition( + opacity: _entranceController, + child: child, +// child: Column(children: [child, Text('appearing $index')]) + ), //Column(children: [spacing, Text('eeeeee $index')]) + ); } Widget _makeDisappearingWidget(Widget child) { - return makeDisappearingWidget(child, _ghostController, null, widget.direction,); + return SizeTransitionWithIntrinsicSize( + sizeFactor: _ghostController, + axis: widget.direction, + child: FadeTransition( + opacity: _ghostController, + child: child, +// child: Column(children: [child, Text('disappearing $index')]) + ), + ); } //Widget buildDragTarget(BuildContext context, List acceptedCandidates, List rejectedCandidates) { @@ -783,20 +794,22 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> Widget child = this.widget.needsLongPressDraggable ? LongPressDraggable( maxSimultaneousDrags: 1, - data: index,//toWrap.key, + data: index, //toWrap.key, ignoringFeedbackSemantics: false, feedback: feedbackBuilder, // Wrap toWrapWithSemantics with a widget that supports HitTestBehavior // to make sure the whole toWrapWithSemantics responds to pointer events, i.e. dragging - child: MetaData(child: toWrapWithSemantics, behavior: HitTestBehavior.opaque), //toWrapWithSemantics,//_dragging == toWrap.key ? const SizedBox() : toWrapWithSemantics, + child: MetaData( + child: toWrapWithSemantics, + behavior: HitTestBehavior + .opaque), //toWrapWithSemantics,//_dragging == toWrap.key ? const SizedBox() : toWrapWithSemantics, childWhenDragging: IgnorePointer( ignoring: true, child: Opacity( - opacity: 0.2, - //child: toWrap,//Container(width: 0, height: 0, child: toWrap) - child: _makeAppearingWidget(toWrap) - ) - ), //ConstrainedBox(constraints: contentConstraints),//SizedBox(), + opacity: 0.2, + //child: toWrap,//Container(width: 0, height: 0, child: toWrap) + child: _makeAppearingWidget( + toWrap))), //ConstrainedBox(constraints: contentConstraints),//SizedBox(), dragAnchor: DragAnchor.child, onDragStarted: onDragStarted, // When the drag ends inside a DragTarget widget, the drag @@ -805,11 +818,12 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // When the drag does not end inside a DragTarget widget, the // drag fails, but we still reorder the widget to the last position it // had been dragged to. - onDraggableCanceled: (Velocity velocity, Offset offset) => onDragEnded(), + onDraggableCanceled: (Velocity velocity, Offset offset) => + onDragEnded(), ) : Draggable( maxSimultaneousDrags: 1, - data: index,//toWrap.key, + data: index, //toWrap.key, ignoringFeedbackSemantics: false, feedback: feedbackBuilder, child: MetaData( @@ -824,7 +838,8 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> dragAnchor: DragAnchor.child, onDragStarted: onDragStarted, onDragCompleted: onDragEnded, - onDraggableCanceled: (Velocity velocity, Offset offset) => onDragEnded(), + onDraggableCanceled: (Velocity velocity, Offset offset) => + onDragEnded(), ); // The target for dropping at the end of the list doesn't need to be @@ -851,40 +866,51 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // debugPrint('index:$index displayIndex:$displayIndex _nextDisplayIndex:$_nextDisplayIndex _currentDisplayIndex:$_currentDisplayIndex _ghostDisplayIndex:$_ghostDisplayIndex _dragStartIndex:$_dragStartIndex'); // debugPrint(' _childRunIndexes:$_childRunIndexes _nextChildRunIndexes:$_nextChildRunIndexes _wrapChildRunIndexes:$_wrapChildRunIndexes'); - List _includeMovedAdjacentChildIfNeeded(Widget child, int childDisplayIndex) { + List _includeMovedAdjacentChildIfNeeded( + Widget child, int childDisplayIndex) { // debugPrint(' checking ${_childDisplayIndexToIndex[childDisplayIndex]}($childDisplayIndex)'); int checkingTargetDisplayIndex = -1; - if (_ghostDisplayIndex < _currentDisplayIndex && childDisplayIndex > _ghostDisplayIndex) { + if (_ghostDisplayIndex < _currentDisplayIndex && + childDisplayIndex > _ghostDisplayIndex) { checkingTargetDisplayIndex = childDisplayIndex - 1; - } else if (_ghostDisplayIndex > _currentDisplayIndex && childDisplayIndex < _ghostDisplayIndex) { + } else if (_ghostDisplayIndex > _currentDisplayIndex && + childDisplayIndex < _ghostDisplayIndex) { checkingTargetDisplayIndex = childDisplayIndex + 1; } if (checkingTargetDisplayIndex == -1) { return [child]; } - int checkingTargetIndex = _childDisplayIndexToIndex[checkingTargetDisplayIndex]; + int checkingTargetIndex = + _childDisplayIndexToIndex[checkingTargetDisplayIndex]; if (checkingTargetIndex == _dragStartIndex) { return [child]; } - if (_childRunIndexes[checkingTargetIndex] == -1 || _childRunIndexes[checkingTargetIndex] == _wrapChildRunIndexes[checkingTargetDisplayIndex]) { + if (_childRunIndexes[checkingTargetIndex] == -1 || + _childRunIndexes[checkingTargetIndex] == + _wrapChildRunIndexes[checkingTargetDisplayIndex]) { return [child]; } // debugPrint(' make $checkingTargetIndex($checkingTargetDisplayIndex) disappearing around $index'); - Widget disappearingPreChild = _makeDisappearingWidget(_wrapChildren[checkingTargetIndex]); + Widget disappearingPreChild = + _makeDisappearingWidget(_wrapChildren[checkingTargetIndex]); // return _buildContainerForMainAxis( // children: _ghostDisplayIndex < _currentDisplayIndex // ? [disappearingPreChild, child] // : [child, disappearingPreChild] // ); // debugPrint('${DateTime.now().toString().substring(5, 22)} reorderable_wrap.dart(874) $this._includeMovedAdjacentChildIfNeeded: ${_ghostDisplayIndex < _currentDisplayIndex}'); - return _ghostDisplayIndex < _currentDisplayIndex ? [disappearingPreChild, child] : [child, disappearingPreChild]; + return _ghostDisplayIndex < _currentDisplayIndex + ? [disappearingPreChild, child] + : [child, disappearingPreChild]; } _nextChildRunIndexes[index] = _wrapChildRunIndexes[displayIndex]; if (_currentDisplayIndex == -1 || displayIndex == _currentDisplayIndex) { //we still wrap dragTarget with a container so that widget's depths are the same and it prevents layout alignment issue - return _buildContainerForMainAxis(children: _includeMovedAdjacentChildIfNeeded(containedDraggable, displayIndex)); + return _buildContainerForMainAxis( + children: _includeMovedAdjacentChildIfNeeded( + containedDraggable, displayIndex)); } bool _onWillAccept(int toAccept, bool isPre) { @@ -895,19 +921,22 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> nextDisplayIndex = !isPre ? displayIndex + 1 : displayIndex; } - bool movingToAdjacentChild = nextDisplayIndex <= _currentDisplayIndex + 1 && nextDisplayIndex >= _currentDisplayIndex - 1; + bool movingToAdjacentChild = + nextDisplayIndex <= _currentDisplayIndex + 1 && + nextDisplayIndex >= _currentDisplayIndex - 1; bool willAccept = _dragStartIndex == toAccept && // toAccept != toWrap.key && - toAccept != index && - (_entranceController.isCompleted || !movingToAdjacentChild) && - _currentDisplayIndex != nextDisplayIndex; + toAccept != index && + (_entranceController.isCompleted || !movingToAdjacentChild) && + _currentDisplayIndex != nextDisplayIndex; // debugPrint('_onWillAccept: index:$index displayIndex:$displayIndex toAccept:$toAccept return:$willAccept isPre:$isPre ' // '_currentDisplayIndex:$_currentDisplayIndex nextDisplayIndex:$nextDisplayIndex _dragStartIndex:$_dragStartIndex'); if (!willAccept) { return false; } - assert(_childDisplayIndexToIndex[_currentDisplayIndex] != index && _currentDisplayIndex != displayIndex); + assert(_childDisplayIndexToIndex[_currentDisplayIndex] != index && + _currentDisplayIndex != displayIndex); if (_wrapKey.currentContext != null) { RenderWrapWithMainAxisCount wrapRenderObject = @@ -939,13 +968,17 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> } Widget preDragTarget = DragTarget( - builder: (BuildContext context, List acceptedCandidates, List rejectedCandidates) => SizedBox(), + builder: (BuildContext context, List acceptedCandidates, + List rejectedCandidates) => + SizedBox(), onWillAccept: (int toAccept) => _onWillAccept(toAccept, true), onAccept: (int accepted) {}, onLeave: (Object leaving) {}, ); Widget nextDragTarget = DragTarget( - builder: (BuildContext context, List acceptedCandidates, List rejectedCandidates) => SizedBox(), + builder: (BuildContext context, List acceptedCandidates, + List rejectedCandidates) => + SizedBox(), onWillAccept: (int toAccept) => _onWillAccept(toAccept, false), onAccept: (int accepted) {}, onLeave: (Object leaving) {}, @@ -1012,7 +1045,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // return willAccept;//_dragging == toAccept && toAccept != toWrap.key; // }, // onAccept: (Key accepted) {}, -// onLeave: (Object leaving) {}, +// onLeave: (Key leaving) {}, // ); // dragTarget = KeyedSubtree( @@ -1035,14 +1068,21 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> Widget ghostSpacing = _makeDisappearingWidget(spacing); if (_ghostDisplayIndex < _currentDisplayIndex) { //ghost is on the left of current, so shift it to the right - return _buildContainerForMainAxis(children: [ghostSpacing] + _includeMovedAdjacentChildIfNeeded(dragTarget, displayIndex)); + return _buildContainerForMainAxis( + children: [ghostSpacing] + + _includeMovedAdjacentChildIfNeeded(dragTarget, displayIndex)); } else if (_ghostDisplayIndex > _currentDisplayIndex) { - return _buildContainerForMainAxis(children: _includeMovedAdjacentChildIfNeeded(dragTarget, displayIndex) + [ghostSpacing]); + return _buildContainerForMainAxis( + children: + _includeMovedAdjacentChildIfNeeded(dragTarget, displayIndex) + + [ghostSpacing]); } } //we still wrap dragTarget with a container so that widget's depths are the same and it prevent's layout alignment issue - return _buildContainerForMainAxis(children: _includeMovedAdjacentChildIfNeeded(dragTarget, displayIndex)); + return _buildContainerForMainAxis( + children: + _includeMovedAdjacentChildIfNeeded(dragTarget, displayIndex)); // if (shiftedIndex == _currentDisplayIndex) { // Widget entranceSpacing = SizeTransitionWithIntrinsicSize( @@ -1088,12 +1128,14 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // _childSizes = List.filled(widget.children.length, Size(0, 0)); List _resizeListMember(List listVar, E initValue) { if (listVar.length < widget.children.length) { - return listVar + List.filled(widget.children.length - listVar.length, initValue); + return listVar + + List.filled(widget.children.length - listVar.length, initValue); } else if (listVar.length > widget.children.length) { return listVar.sublist(0, widget.children.length); } return listVar; } + // _childKeys = _resizeListMember(_childKeys, null); _childContexts = _resizeListMember(_childContexts, null); _childSizes = _resizeListMember(_childSizes, Size(0, 0)); @@ -1101,7 +1143,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> _childDisplayIndexToIndex = List.generate(widget.children.length, (int index) => index); _childIndexToDisplayIndex = - List.generate(widget.children.length, (int index) => index); + List.generate(widget.children.length, (int index) => index); if (_dragStartIndex >= 0 && _currentDisplayIndex >= 0 && _dragStartIndex != _currentDisplayIndex) { @@ -1175,11 +1217,16 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> transform: new Matrix4.rotationZ(0), alignment: FractionalOffset.topLeft, child: Material( - child: - Card(child: ConstrainedBox(constraints: constraints, child: child)), + child: Card( + shape: RoundedRectangleBorder( + borderRadius: widget.borderRadiusOnDrag ?? BorderRadius.zero, + ), + child: ConstrainedBox(constraints: constraints, child: child)), elevation: 6.0, color: Colors.transparent, - borderRadius: BorderRadius.zero, + shape: RoundedRectangleBorder( + borderRadius: widget.borderRadiusOnDrag ?? BorderRadius.zero, + ), ), ); }