Drag and drop only works on first
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
add a comment |
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
add a comment |
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
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
android user-interface
edited Nov 25 '18 at 14:21
Tiago Redaelli
asked Nov 25 '18 at 9:50
Tiago RedaelliTiago Redaelli
32229
32229
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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...
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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...
add a comment |
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...
add a comment |
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...
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...
answered Nov 25 '18 at 15:59
Tiago RedaelliTiago Redaelli
32229
32229
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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