Drag and drop only works on first












0















I have a map of nodes and a circle that can be moved around the nodes using drag and drop. However, after a node has been used and the circle is moved it can no longer be moved back to the same node unless I rotate the screen, resetting everything. Why is this the case?



Secondly on a practical level, do I need to recreate the used component after each successful drop or how should I resolve this issue?



I'm using observables to update the UI:



private void handleObservedCheckers() {
mainViewModel.checkerLiveData.observe(this, new Observer<Collection<Checker>>() {
@Override
public void onChanged(@Nullable Collection<Checker> checkers) {
if (checkers == null)
return;
Log.d(TAG, checkers.toString());
for (Checker checker : checkers) {
CheckerView view = (CheckerView) nodeMap.get(checker.getPosition());
view.invalidate();
if (checker.getColor() == Color.RED) {
view.paintRed();
view.show();
}
else if (checker.getColor() == Color.BLUE) {
view.paintBlue();
view.show();
} else {
view.hide();
}
view.draggable = checker.isDraggable();
//view.invalidate();
}
}
});
}


And the view component is created onCreate



private View createChecker(int x, int y, int size, Position position) {
final CheckerView view = new CheckerView(this, x, y, size, position);
view.show();
view.draggable = false;
// Maps the view to the given position
nodeMap.put(position, view);
checkerViewList.add(view);
Log.d(TAG, "created: " + view.toString());

view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (view.draggable && event.getAction() == MotionEvent.ACTION_DOWN) {
// Save the position as clip data to be retrieved on drop
ClipData.Item item = new ClipData.Item("" + view.position);
ClipData data = new ClipData("", new String{ClipDescription.MIMETYPE_TEXT_PLAIN}, item);
// Start drag
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDragAndDrop(data, shadowBuilder, view, 0);
return true;
} else {
return false;
}
}
});
view.setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
return true;
case DragEvent.ACTION_DRAG_EXITED:
return true;
case DragEvent.ACTION_DRAG_LOCATION:
return true;
case DragEvent.ACTION_DRAG_ENTERED:
return true;
case DragEvent.ACTION_DROP:
Log.w(TAG, "dropped");
// get stored position inside clip data if any exists
String data = (String) event.getClipData().getItemAt(0).getText();
if (!data.equals("")) {
mainViewModel.moveChecker(Position.valueOf(data), view.position);
} else {
mainViewModel.placeChecker(view.position);
}

return true;
case DragEvent.ACTION_DRAG_ENDED:
return true;
default:
return true;
}
}
});
return view;
}


I changed to redraw on each cycle, this time I constantly get "Reporting drop result: false" instead. (Ref: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewRootImpl.java)










share|improve this question





























    0















    I have a map of nodes and a circle that can be moved around the nodes using drag and drop. However, after a node has been used and the circle is moved it can no longer be moved back to the same node unless I rotate the screen, resetting everything. Why is this the case?



    Secondly on a practical level, do I need to recreate the used component after each successful drop or how should I resolve this issue?



    I'm using observables to update the UI:



    private void handleObservedCheckers() {
    mainViewModel.checkerLiveData.observe(this, new Observer<Collection<Checker>>() {
    @Override
    public void onChanged(@Nullable Collection<Checker> checkers) {
    if (checkers == null)
    return;
    Log.d(TAG, checkers.toString());
    for (Checker checker : checkers) {
    CheckerView view = (CheckerView) nodeMap.get(checker.getPosition());
    view.invalidate();
    if (checker.getColor() == Color.RED) {
    view.paintRed();
    view.show();
    }
    else if (checker.getColor() == Color.BLUE) {
    view.paintBlue();
    view.show();
    } else {
    view.hide();
    }
    view.draggable = checker.isDraggable();
    //view.invalidate();
    }
    }
    });
    }


    And the view component is created onCreate



    private View createChecker(int x, int y, int size, Position position) {
    final CheckerView view = new CheckerView(this, x, y, size, position);
    view.show();
    view.draggable = false;
    // Maps the view to the given position
    nodeMap.put(position, view);
    checkerViewList.add(view);
    Log.d(TAG, "created: " + view.toString());

    view.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    if (view.draggable && event.getAction() == MotionEvent.ACTION_DOWN) {
    // Save the position as clip data to be retrieved on drop
    ClipData.Item item = new ClipData.Item("" + view.position);
    ClipData data = new ClipData("", new String{ClipDescription.MIMETYPE_TEXT_PLAIN}, item);
    // Start drag
    View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
    view.startDragAndDrop(data, shadowBuilder, view, 0);
    return true;
    } else {
    return false;
    }
    }
    });
    view.setOnDragListener(new View.OnDragListener() {
    @Override
    public boolean onDrag(View v, DragEvent event) {
    switch (event.getAction()) {
    case DragEvent.ACTION_DRAG_STARTED:
    return true;
    case DragEvent.ACTION_DRAG_EXITED:
    return true;
    case DragEvent.ACTION_DRAG_LOCATION:
    return true;
    case DragEvent.ACTION_DRAG_ENTERED:
    return true;
    case DragEvent.ACTION_DROP:
    Log.w(TAG, "dropped");
    // get stored position inside clip data if any exists
    String data = (String) event.getClipData().getItemAt(0).getText();
    if (!data.equals("")) {
    mainViewModel.moveChecker(Position.valueOf(data), view.position);
    } else {
    mainViewModel.placeChecker(view.position);
    }

    return true;
    case DragEvent.ACTION_DRAG_ENDED:
    return true;
    default:
    return true;
    }
    }
    });
    return view;
    }


    I changed to redraw on each cycle, this time I constantly get "Reporting drop result: false" instead. (Ref: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewRootImpl.java)










    share|improve this question



























      0












      0








      0








      I have a map of nodes and a circle that can be moved around the nodes using drag and drop. However, after a node has been used and the circle is moved it can no longer be moved back to the same node unless I rotate the screen, resetting everything. Why is this the case?



      Secondly on a practical level, do I need to recreate the used component after each successful drop or how should I resolve this issue?



      I'm using observables to update the UI:



      private void handleObservedCheckers() {
      mainViewModel.checkerLiveData.observe(this, new Observer<Collection<Checker>>() {
      @Override
      public void onChanged(@Nullable Collection<Checker> checkers) {
      if (checkers == null)
      return;
      Log.d(TAG, checkers.toString());
      for (Checker checker : checkers) {
      CheckerView view = (CheckerView) nodeMap.get(checker.getPosition());
      view.invalidate();
      if (checker.getColor() == Color.RED) {
      view.paintRed();
      view.show();
      }
      else if (checker.getColor() == Color.BLUE) {
      view.paintBlue();
      view.show();
      } else {
      view.hide();
      }
      view.draggable = checker.isDraggable();
      //view.invalidate();
      }
      }
      });
      }


      And the view component is created onCreate



      private View createChecker(int x, int y, int size, Position position) {
      final CheckerView view = new CheckerView(this, x, y, size, position);
      view.show();
      view.draggable = false;
      // Maps the view to the given position
      nodeMap.put(position, view);
      checkerViewList.add(view);
      Log.d(TAG, "created: " + view.toString());

      view.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
      if (view.draggable && event.getAction() == MotionEvent.ACTION_DOWN) {
      // Save the position as clip data to be retrieved on drop
      ClipData.Item item = new ClipData.Item("" + view.position);
      ClipData data = new ClipData("", new String{ClipDescription.MIMETYPE_TEXT_PLAIN}, item);
      // Start drag
      View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
      view.startDragAndDrop(data, shadowBuilder, view, 0);
      return true;
      } else {
      return false;
      }
      }
      });
      view.setOnDragListener(new View.OnDragListener() {
      @Override
      public boolean onDrag(View v, DragEvent event) {
      switch (event.getAction()) {
      case DragEvent.ACTION_DRAG_STARTED:
      return true;
      case DragEvent.ACTION_DRAG_EXITED:
      return true;
      case DragEvent.ACTION_DRAG_LOCATION:
      return true;
      case DragEvent.ACTION_DRAG_ENTERED:
      return true;
      case DragEvent.ACTION_DROP:
      Log.w(TAG, "dropped");
      // get stored position inside clip data if any exists
      String data = (String) event.getClipData().getItemAt(0).getText();
      if (!data.equals("")) {
      mainViewModel.moveChecker(Position.valueOf(data), view.position);
      } else {
      mainViewModel.placeChecker(view.position);
      }

      return true;
      case DragEvent.ACTION_DRAG_ENDED:
      return true;
      default:
      return true;
      }
      }
      });
      return view;
      }


      I changed to redraw on each cycle, this time I constantly get "Reporting drop result: false" instead. (Ref: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewRootImpl.java)










      share|improve this question
















      I have a map of nodes and a circle that can be moved around the nodes using drag and drop. However, after a node has been used and the circle is moved it can no longer be moved back to the same node unless I rotate the screen, resetting everything. Why is this the case?



      Secondly on a practical level, do I need to recreate the used component after each successful drop or how should I resolve this issue?



      I'm using observables to update the UI:



      private void handleObservedCheckers() {
      mainViewModel.checkerLiveData.observe(this, new Observer<Collection<Checker>>() {
      @Override
      public void onChanged(@Nullable Collection<Checker> checkers) {
      if (checkers == null)
      return;
      Log.d(TAG, checkers.toString());
      for (Checker checker : checkers) {
      CheckerView view = (CheckerView) nodeMap.get(checker.getPosition());
      view.invalidate();
      if (checker.getColor() == Color.RED) {
      view.paintRed();
      view.show();
      }
      else if (checker.getColor() == Color.BLUE) {
      view.paintBlue();
      view.show();
      } else {
      view.hide();
      }
      view.draggable = checker.isDraggable();
      //view.invalidate();
      }
      }
      });
      }


      And the view component is created onCreate



      private View createChecker(int x, int y, int size, Position position) {
      final CheckerView view = new CheckerView(this, x, y, size, position);
      view.show();
      view.draggable = false;
      // Maps the view to the given position
      nodeMap.put(position, view);
      checkerViewList.add(view);
      Log.d(TAG, "created: " + view.toString());

      view.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
      if (view.draggable && event.getAction() == MotionEvent.ACTION_DOWN) {
      // Save the position as clip data to be retrieved on drop
      ClipData.Item item = new ClipData.Item("" + view.position);
      ClipData data = new ClipData("", new String{ClipDescription.MIMETYPE_TEXT_PLAIN}, item);
      // Start drag
      View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
      view.startDragAndDrop(data, shadowBuilder, view, 0);
      return true;
      } else {
      return false;
      }
      }
      });
      view.setOnDragListener(new View.OnDragListener() {
      @Override
      public boolean onDrag(View v, DragEvent event) {
      switch (event.getAction()) {
      case DragEvent.ACTION_DRAG_STARTED:
      return true;
      case DragEvent.ACTION_DRAG_EXITED:
      return true;
      case DragEvent.ACTION_DRAG_LOCATION:
      return true;
      case DragEvent.ACTION_DRAG_ENTERED:
      return true;
      case DragEvent.ACTION_DROP:
      Log.w(TAG, "dropped");
      // get stored position inside clip data if any exists
      String data = (String) event.getClipData().getItemAt(0).getText();
      if (!data.equals("")) {
      mainViewModel.moveChecker(Position.valueOf(data), view.position);
      } else {
      mainViewModel.placeChecker(view.position);
      }

      return true;
      case DragEvent.ACTION_DRAG_ENDED:
      return true;
      default:
      return true;
      }
      }
      });
      return view;
      }


      I changed to redraw on each cycle, this time I constantly get "Reporting drop result: false" instead. (Ref: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewRootImpl.java)







      android user-interface






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 25 '18 at 14:21







      Tiago Redaelli

















      asked Nov 25 '18 at 9:50









      Tiago RedaelliTiago Redaelli

      32229




      32229
























          1 Answer
          1






          active

          oldest

          votes


















          0














          The problem with attaching a drag listener to the same component as the on touch listner (for shadow drag) is that it will only be able to register drops onto itself it seems...






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53466349%2fdrag-and-drop-only-works-on-first%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            The problem with attaching a drag listener to the same component as the on touch listner (for shadow drag) is that it will only be able to register drops onto itself it seems...






            share|improve this answer




























              0














              The problem with attaching a drag listener to the same component as the on touch listner (for shadow drag) is that it will only be able to register drops onto itself it seems...






              share|improve this answer


























                0












                0








                0







                The problem with attaching a drag listener to the same component as the on touch listner (for shadow drag) is that it will only be able to register drops onto itself it seems...






                share|improve this answer













                The problem with attaching a drag listener to the same component as the on touch listner (for shadow drag) is that it will only be able to register drops onto itself it seems...







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 25 '18 at 15:59









                Tiago RedaelliTiago Redaelli

                32229




                32229






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53466349%2fdrag-and-drop-only-works-on-first%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

                    Calculate evaluation metrics using cross_val_predict sklearn

                    Insert data from modal to MySQL (multiple modal on website)