knopp / flutter_reorderable_list

ReorderableList for Flutter
BSD 3-Clause "New" or "Revised" License
335 stars 98 forks source link

When dragging multiple times I get this error #10

Closed hyperpanthera closed 5 years ago

hyperpanthera commented 5 years ago

If you use the handle to change the order of an item, drop the handle then quickly try to move another handle, you get an error like update() called on null at line: (package:flutter_reorderable_list/flutter_reorderable_list.dart:243:17)

I/flutter (32332): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════ I/flutter (32332): The following NoSuchMethodError was thrown while handling a gesture: I/flutter (32332): The method 'update' was called on null. I/flutter (32332): Receiver: null I/flutter (32332): Tried calling: update() I/flutter (32332): I/flutter (32332): When the exception was thrown, this was the stack: I/flutter (32332): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:50:5) I/flutter (32332): #1 _ReorderableListState._dragStart (package:flutter_reorderable_list/flutter_reorderable_list.dart:243:17) I/flutter (32332): #2 MultiDragGestureRecognizer._startDrag. (package:flutter/src/gestures/multidrag.dart:266:52) I/flutter (32332): #3 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24) I/flutter (32332): #4 MultiDragGestureRecognizer._startDrag (package:flutter/src/gestures/multidrag.dart:266:14) I/flutter (32332): #5 MultiDragGestureRecognizer.acceptGesture. (package:flutter/src/gestures/multidrag.dart:256:48) I/flutter (32332): #6 _VerticalPointerState.accepted (package:flutter_reorderable_list/flutter_reorderable_list.dart:736:12) I/flutter (32332): #7 MultiDragGestureRecognizer.acceptGesture (package:flutter/src/gestures/multidrag.dart:256:11) I/flutter (32332): #8 GestureArenaManager._resolveInFavorOf (package:flutter/src/gestures/arena.dart:263:12) I/flutter (32332): #9 GestureArenaManager._resolve (package:flutter/src/gestures/arena.dart:222:9) I/flutter (32332): #10 GestureArenaEntry.resolve (package:flutter/src/gestures/arena.dart:52:12) I/flutter (32332): #11 MultiDragPointerState.resolve (package:flutter/src/gestures/multidrag.dart:62:17) I/flutter (32332): #12 _VerticalPointerState.checkForResolutionAfterMove (package:flutter_reorderable_list/flutter_reorderable_list.dart:731:7) I/flutter (32332): #13 MultiDragPointerState._move (package:flutter/src/gestures/multidrag.dart:81:7) I/flutter (32332): #14 MultiDragGestureRecognizer._handleEvent (package:flutter/src/gestures/multidrag.dart:230:13) I/flutter (32332): #15 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:75:13) I/flutter (32332): #16 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:102:11) I/flutter (32332): #17 _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19) I/flutter (32332): #18 _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22) I/flutter (32332): #19 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7) I/flutter (32332): #20 _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7) I/flutter (32332): #21 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7) I/flutter (32332): #25 _invoke1 (dart:ui/hooks.dart:250:10) I/flutter (32332): #26 _dispatchPointerDataPacket (dart:ui/hooks.dart:159:5) I/flutter (32332): (elided 3 frames from package dart:async) I/flutter (32332): I/flutter (32332): Handler: "onStart" I/flutter (32332): Recognizer: I/flutter (32332): _Recognizer#1b65b I/flutter (32332): ════════════════════════════════════════════════════════════════════════════════════════════════════

After that you can't move any of the handles anymore. It gets broken. Try around a few times then you will see. I use ListTiles.

knopp commented 5 years ago

Is this reproducible with the provided example?

knopp commented 5 years ago

Also, please wrap the stacktrace with ``` to format it properly

hyperpanthera commented 5 years ago

@knopp I will try the provided example tomorrow and report back. Late here at the moment.

I used only ListTile's so far. Thanks for the answer.

knopp commented 5 years ago

Also, do your ReorderableItems have stable keys?

hyperpanthera commented 5 years ago

@knopp Yes, I am displaying categories as ListTiles. As key, I am using the unique ids of the categories. No duplicates at all.

I will try it on the example tomorrow and report back. I'm curious now if I can replicate it.

hyperpanthera commented 5 years ago

Everything works in my app if I make a pause like 1 - 2 seconds before using the handle again.

hyperpanthera commented 5 years ago

@knopp It works smoothly in the example provided by your library.

I will try to figure out the problem in my code to report back on here for people that may end up with the same issue.

knopp commented 5 years ago

If you can provide a minimal reproducible example I can look into that.

hyperpanthera commented 5 years ago

@knopp

If I remove rebuildStates(); the error vanishes.

rebuildStates() just does setState() for the parent widget. Also if I remove it, the names mess up after I move a ListTile, then redrag the previously moved ListTile.

It's this library: https://pub.dev/packages/states_rebuilder

knopp commented 5 years ago

Well, the reorder function ReorderableList takes provides two keys, not indices. So it looks like maybe you're using another layer there, in which case I'm not sure I can help you here.

I'm also not sure what rebuildStates does and why it is even necessary. Does your UI inside the list change on reodrer (other than reordering items)?

As far as I can tell from the initial error report, it looks like the key/indices get out of sync at some point. I made a deliberate decision in the tree to always work with keys instead of indices in tree api, because keys are supposed to be stable for reach item where as indices change during reodering.

hyperpanthera commented 5 years ago

@knopp Yes, I am using this as extra layer: https://gist.githubusercontent.com/ffeu/127c2b76d891fa12c9e2c831def785c4/raw/ceb07bab84f4e1fac685290cb3e50973a56cd20e/reorderable_list_simple.dart

However, the extra layer works in its provided demo. I will need to figure out what the problem in my case is.

hyperpanthera commented 5 years ago

@knopp The issue was resolved after I removed async from onReorder(), seems like doing await in onReorder() is not a good idea!