sanedroid
sanedroid

Reputation: 1036

Creating launcher like drag and drop with multiple screens in android

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?

Upvotes: 1

Views: 2214

Answers (2)

Rajesh
Rajesh

Reputation: 11

I just wrote this: (its working for the time being)

  1. Just addDragListener only on ViewPager. You don't need to addDragListener on gridviews.

  2. Get Position of Drop on target Grid.

  3. Keep track of source GridView and Target Gridview and use to get its adapter.

  4. 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          
                );

Upvotes: 1

rajesh
rajesh

Reputation: 1

  1. Use ViewPager for multiple pages.
  2. Use GridView (in fragment) on ViewPager on each viewpager page.
  3. setOnDragListener on viewPager only once // important
  4. setOnDragListener on each GridView on pages// important
  5. get position = pointToPosition(event.getX(),event.getY()) on target GridView on ACTION_DROP (add here ur icon or what ever u r moving).
  6. ACTION_DRAG_END to use for removing from the source GridView.
  7. 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.

Upvotes: 0

Related Questions