I want to implement a layout where I can drag an image and drop it to another screen similar to android launcher where we can place the app icons anywhere on a set of screens scrolling horizontally. I am not sure how to start and where to start. I am thinking of implementing a layout that would be larger than screen and then start autoscrolling as soon as the user touches the image.The position of dropping the image will be fixed. Any references or better approach to implement this?
Asked
Active
Viewed 1,936 times
1
-
Try this http://www.tutorialspoint.com/android/android_drag_and_drop.htm – Sukhwant Singh Grewal Mar 20 '15 at 07:19
-
1The tutorial is based on one screen.. I am looking for multiple screens – sanedroid Mar 20 '15 at 07:48
-
Use Viewpager instead. – Tushar Gogna Mar 20 '15 at 09:24
-
I did thought of using viewpager.. But I am not sure how I will drag the image from 1st page to 2nd page in viewpager?? – sanedroid Mar 20 '15 at 09:29
-
1There is a lib for that. See [this](https://github.com/geftimov/android-draggable-viewpager). – Tushar Gogna Mar 20 '15 at 09:31
-
hey Tushar.. the demo is working.. thanks for helping.. :) – sanedroid Mar 20 '15 at 09:58
-
@Tushar - Will you please visit this link http://stackoverflow.com/questions/29181440/android-animating-views-between-pages and help me with your valuable suggestions – sanedroid Mar 21 '15 at 10:28
-
You can talk [here](http://chat.stackoverflow.com/rooms/71661/android-discussions) regarding your queries. – Tushar Gogna Mar 21 '15 at 11:39
-
Hello! Did you manage to do it? Can you show how you did it? – DuosDuo May 24 '18 at 10:10
2 Answers
1
I just wrote this: (its working for the time being)
Just addDragListener only on ViewPager. You don't need to addDragListener on gridviews.
Get Position of Drop on target Grid.
Keep track of source GridView and Target Gridview and use to get its adapter.
then Manipulate on Drop between adapter.
public void setDragListener() {
pager = getViewPager();
dragListener = new View.OnDragListener() {
GridViewAdapter sourceAdapter = null;
GridViewAdapter targetAdapter = null;
int currentOffset = 0;
@Override
public boolean onDrag(View v, DragEvent event) {
int currentX = -1;
int currentY = -1;
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
if (!pager.isFakeDragging()) {
pager.beginFakeDrag();
}
break;
case DragEvent.ACTION_DRAG_ENTERED:
pager.setCurrentItem(pager.getCurrentItem());
currentOffset = (int) (event.getX());
if (!pager.isFakeDragging()) {
pager.beginFakeDrag();
}
break;
case DragEvent.ACTION_DRAG_EXITED:
break;
case DragEvent.ACTION_DRAG_LOCATION:
if (pager != null) {
if (!pager.isFakeDragging()) {
pager.beginFakeDrag();
}
if (pager.isFakeDragging()) {
int maxWidth = pager.getWidth() * pager.getCount();
int offset = (int) (event.getX());
int scrollX = getScrollX();
int dragBy = (int) -1 * (offset - currentOffset);
currentOffset = offset;
pager.fakeDragBy(dragBy * pager.getCount());
int scrolledPage = (int) (offset + scrollX) / pager.getWidth();
if (pager.getCurrentItem() != scrolledPage) {
pager.setCurrentItem(Math.abs(scrolledPage));
}
}
}
break;
case DragEvent.ACTION_DRAG_ENDED:
if (pager.isFakeDragging()) {
pager.endFakeDrag();
}
break;
case DragEvent.ACTION_DROP:
if (pager.isFakeDragging()) {
pager.endFakeDrag();
}
currentX = (int) event.getX();
currentY = (int) event.getY();
// u can use meta data and other info which u passed when longPress
// u can set sourcePage and sourcePosition in meta data.
metaMove = event.getLocalState();
sourceAdapter = // get Source Gridviews adapter
targetAdapter = // get Target GridViews Adapter ie current Page's gridviews adapter.
GridView g = // get The gridview current Page gridview
if (g != null) {
int position = g.pointToPosition(currentX + (getScrollX() - (pager.getWidth() * pager.getCurrentItem())), currentY);
metaMove.targetPosition = position;
metaMove.targetPage = currentPage;
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
// u can move from source to target by inset and remove.
// use some broadcast function to reset if page does not have any item left while moving. Ur logic here.
move(sourceAdapter, targetAdapter, metaMove);
}
});
}
break;
default:
break;
}
return true;
}
};
pager.setOnDragListener(dragListener);
}
public int getScrollX() {
int maxWidth = pager.getWidth() * pager.getCount();
int scrollX = pager.getScrollX();
if (pager.getScrollX() < 0) {
scrollX = maxWidth + scrollX - pager.getWidth();
} else if (pager.getScrollX() == 0) {
if (pager.getCurrentItem() == (pager.getCount() - 1)) {
scrollX = maxWidth + scrollX - pager.getWidth();
}
}
return scrollX;
}
Use following onLongPress on your sourceGrid:
metaMove.sourcePage = // sourcePage;
metaMove.sourcePosition = position;
metaMove.targetPosition = -1; // to be set on drop
metaMove.targetPage = -1 // to be set on drop;
boolean dragStarted = view.startDrag(null,
myShadow,
metaMove,
0
);

Rajesh
- 11
- 2
0
- Use ViewPager for multiple pages.
- Use GridView (in fragment) on ViewPager on each viewpager page.
- setOnDragListener on viewPager only once // important
- setOnDragListener on each GridView on pages// important
- get position = pointToPosition(event.getX(),event.getY()) on target GridView on ACTION_DROP (add here ur icon or what ever u r moving).
- ACTION_DRAG_END to use for removing from the source GridView.
- use ACTION_DRAG_EXIT from gridView to change viewPager page to & fro.
Note : I assume you are using gridView.setOnItemLongClickListener()
for startDrag() etc. Refer it on android site.

rajesh
- 1
- 1