@@ -14,6 +14,23 @@ import 'dart:ui' show lerpDouble;
1414typedef bool ReorderItemCallback (Key draggedItem, Key newPosition);
1515typedef void ReorderCompleteCallback (Key draggedItem);
1616
17+ // Represents placeholder for currently dragged row including decorations
18+ // (i.e. before and after shadow)
19+ class DecoratedPlaceholder {
20+ DecoratedPlaceholder ({
21+ this .offset,
22+ this .widget,
23+ });
24+
25+ // Height of decoration before widget
26+ final double offset;
27+ final Widget widget;
28+ }
29+
30+ // Decorates current placeholder widget
31+ typedef DecoratedPlaceholder DecoratePlaceholder (
32+ Widget widget, double decorationOpacity);
33+
1734// Can be used to cancel reordering (i.e. when underlying data changed)
1835class CancellationToken {
1936 void cancelDragging () {
@@ -32,12 +49,14 @@ class ReorderableList extends StatefulWidget {
3249 @required this .onReorder,
3350 this .onReorderDone,
3451 this .cancellationToken,
52+ this .decoratePlaceholder = _defaultDecoratePlaceholder,
3553 }) : super (key: key);
3654
3755 final Widget child;
3856
3957 final ReorderItemCallback onReorder;
4058 final ReorderCompleteCallback onReorderDone;
59+ final DecoratePlaceholder decoratePlaceholder;
4160
4261 final CancellationToken cancellationToken;
4362
@@ -152,7 +171,10 @@ class _ReorderableListState extends State<ReorderableList>
152171 Widget build (BuildContext context) {
153172 return new Stack (
154173 fit: StackFit .passthrough,
155- children: < Widget > [widget.child, new _DragProxy ()],
174+ children: < Widget > [
175+ widget.child,
176+ new _DragProxy (widget.decoratePlaceholder)
177+ ],
156178 );
157179 }
158180
@@ -361,7 +383,7 @@ class _ReorderableListState extends State<ReorderableList>
361383 _finalAnimation.addListener (() {
362384 _dragProxy.offset =
363385 lerpDouble (dragProxyOffset, originalOffset, _finalAnimation.value);
364- _dragProxy.shadowOpacity = 1.0 - _finalAnimation.value;
386+ _dragProxy.decorationOpacity = 1.0 - _finalAnimation.value;
365387 });
366388
367389 _recognizer? .dispose ();
@@ -594,8 +616,12 @@ class _ReorderableItemState extends State<ReorderableItem> {
594616//
595617
596618class _DragProxy extends StatefulWidget {
619+ final DecoratePlaceholder decoratePlaceholder;
620+
597621 @override
598622 State <StatefulWidget > createState () => new _DragProxyState ();
623+
624+ _DragProxy (this .decoratePlaceholder);
599625}
600626
601627class _DragProxyState extends State <_DragProxy > {
@@ -608,7 +634,7 @@ class _DragProxyState extends State<_DragProxy> {
608634
609635 void setWidget (Widget widget, RenderBox position) {
610636 setState (() {
611- _shadowOpacity = 1.0 ;
637+ _decorationOpacity = 1.0 ;
612638 _widget = widget;
613639 final state = _ReorderableListState .of (context);
614640 RenderBox renderBox = state.context.findRenderObject ();
@@ -633,11 +659,11 @@ class _DragProxyState extends State<_DragProxy> {
633659
634660 get height => _size.height;
635661
636- double _shadowOpacity ;
662+ double _decorationOpacity ;
637663
638- set shadowOpacity (double val) {
664+ set decorationOpacity (double val) {
639665 setState (() {
640- _shadowOpacity = val;
666+ _decorationOpacity = val;
641667 });
642668 }
643669
@@ -652,63 +678,27 @@ class _DragProxyState extends State<_DragProxy> {
652678 final state = _ReorderableListState .of (context);
653679 state._dragProxy = this ;
654680
655- final double decorationHeight = 10.0 ;
656- final mq = MediaQuery .of (context);
657-
658- return _widget != null && _size != null && _offset != null
659- ? new Positioned .fromRect (
660- child: Column (
661- crossAxisAlignment: CrossAxisAlignment .stretch,
662- children: < Widget > [
663- Opacity (
664- opacity: _shadowOpacity,
665- child: Container (
666- height: decorationHeight,
667- decoration: BoxDecoration (
668- border: Border (
669- bottom: BorderSide (
670- color: Color (0x50000000 ),
671- width: 1.0 / mq.devicePixelRatio)),
672- gradient: LinearGradient (
673- begin: Alignment (0.0 , - 1.0 ),
674- end: Alignment (0.0 , 1.0 ),
675- colors: < Color > [
676- Color (0x00000000 ),
677- Color (0x10000000 ),
678- Color (0x30000000 )
679- ])),
680- )),
681- IgnorePointer (
682- child: MediaQuery .removePadding (
683- context: context,
684- child: _widget,
685- removeTop: true ,
686- removeBottom: true ,
687- ),
688- ),
689- Opacity (
690- opacity: _shadowOpacity,
691- child: Container (
692- height: decorationHeight,
693- decoration: BoxDecoration (
694- border: Border (
695- top: BorderSide (
696- color: Color (0x50000000 ),
697- width: 1.0 / mq.devicePixelRatio)),
698- gradient: LinearGradient (
699- begin: Alignment (0.0 , - 1.0 ),
700- end: Alignment (0.0 , 1.0 ),
701- colors: < Color > [
702- Color (0x30000000 ),
703- Color (0x10000000 ),
704- Color (0x00000000 )
705- ])),
706- )),
707- ],
708- ),
709- rect: new Rect .fromLTWH (_offsetX, _offset - decorationHeight,
710- _size.width, _size.height + decorationHeight * 2 + 1.0 ))
711- : new Container (width: 0.0 , height: 0.0 );
681+ if (_widget != null && _size != null && _offset != null ) {
682+ final w = IgnorePointer (
683+ child: MediaQuery .removePadding (
684+ context: context,
685+ child: _widget,
686+ removeTop: true ,
687+ removeBottom: true ,
688+ ),
689+ );
690+
691+ final decoratedPlaceholder =
692+ widget.decoratePlaceholder (w, _decorationOpacity);
693+ return Positioned (
694+ child: decoratedPlaceholder.widget,
695+ left: _offsetX,
696+ width: _size.width,
697+ top: offset - decoratedPlaceholder.offset,
698+ );
699+ } else {
700+ return new Container (width: 0.0 , height: 0.0 );
701+ }
712702 }
713703
714704 @override
@@ -762,3 +752,55 @@ class _Recognizer extends MultiDragGestureRecognizer<_VerticalPointerState> {
762752 @override
763753 String get debugDescription => "Vertical recognizer" ;
764754}
755+
756+ DecoratedPlaceholder _defaultDecoratePlaceholder (
757+ Widget widget, double decorationOpacity) {
758+ final double decorationHeight = 10.0 ;
759+
760+ final decoratedWidget = Builder (builder: (BuildContext context) {
761+ final mq = MediaQuery .of (context);
762+ return Column (
763+ crossAxisAlignment: CrossAxisAlignment .stretch,
764+ children: < Widget > [
765+ Opacity (
766+ opacity: decorationOpacity,
767+ child: Container (
768+ height: decorationHeight,
769+ decoration: BoxDecoration (
770+ border: Border (
771+ bottom: BorderSide (
772+ color: Color (0x50000000 ),
773+ width: 1.0 / mq.devicePixelRatio)),
774+ gradient: LinearGradient (
775+ begin: Alignment (0.0 , - 1.0 ),
776+ end: Alignment (0.0 , 1.0 ),
777+ colors: < Color > [
778+ Color (0x00000000 ),
779+ Color (0x10000000 ),
780+ Color (0x30000000 )
781+ ])),
782+ )),
783+ widget,
784+ Opacity (
785+ opacity: decorationOpacity,
786+ child: Container (
787+ height: decorationHeight,
788+ decoration: BoxDecoration (
789+ border: Border (
790+ top: BorderSide (
791+ color: Color (0x50000000 ),
792+ width: 1.0 / mq.devicePixelRatio)),
793+ gradient: LinearGradient (
794+ begin: Alignment (0.0 , - 1.0 ),
795+ end: Alignment (0.0 , 1.0 ),
796+ colors: < Color > [
797+ Color (0x30000000 ),
798+ Color (0x10000000 ),
799+ Color (0x00000000 )
800+ ])),
801+ )),
802+ ]);
803+ });
804+ return DecoratedPlaceholder (
805+ offset: decorationHeight, widget: decoratedWidget);
806+ }
0 commit comments