Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag and Drop in GridView in Android

How can a drag and drop functionality be implemented in Android GridView. Can anyone please provide the best link for the same?

like image 611
Gaurav Arora Avatar asked Oct 02 '12 12:10

Gaurav Arora


4 Answers

see PagedDragDropGrid

Above example has implemented a paged grid with drag'n'drop movable items using ViewGroup.

Note@ It supports Android 2.2 (API 8) and above.

like image 98
Chirag Patel Avatar answered Nov 15 '22 19:11

Chirag Patel


This is finest example i ever seen in android drag and drop android 2.2. And which version you have used?

like image 45
Hardik Joshi Avatar answered Nov 15 '22 18:11

Hardik Joshi


You can find the google's documentation on drag and drop here and a third parties example here.

What you're going to want to do is set every view in your gridView to be clickable and set the onTouchListener. In your onTouch method you would then handle the appropriate actions for ACTION_DOWN (user pressed down on screen), ACTION_MOVE (user moves finger around ont he screen) and ACTION_UP (user lifts finger from the screen).

like image 32
zabawaba99 Avatar answered Nov 15 '22 18:11

zabawaba99


Try another approach by using WindowManager :

    package com.example.cooldraganddrop;

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Color;
    import android.graphics.PixelFormat;
    import android.graphics.drawable.BitmapDrawable;

    import android.util.AttributeSet;
    import android.view.Gravity;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.AdapterView;
    import android.widget.ImageView;

    public class CoolDragAndDropGridView extends SpanVariableGridView implements `View.OnTouchListener {`

        private static final int ITEM_HOVER_DELAY = 450;

        private int mDragPointX;
        private int mDragPointY;
        private int mDragOffsetX;
        private int mDragOffsetY;
        private int mDragPosition = AdapterView.INVALID_POSITION;
        private int mDropPosition = AdapterView.INVALID_POSITION;
        private int mCurrentPosition = AdapterView.INVALID_POSITION;
        private Runnable mDelayedOnDragRunnable = null;

        ScrollingStrategy mScrollingStrategy = null;
        WindowManager mWindowManager = null;
        WindowManager.LayoutParams mWindowParams = null;
        private ImageView mDragImageView = null;
        private boolean mDragAndDropStarted = false;
        private DragAndDropListener mDragAndDropListener = null;
        private OnTrackTouchEventsListener mOnTrackTouchEventsListener = null;

        public static interface OnTrackTouchEventsListener {

                void trackTouchEvents(final MotionEvent motionEvent);

        };

        public static interface DragAndDropListener {

                void onDragItem(int from);

                void onDraggingItem(int from, int to);

                void onDropItem(int from, int to);

                boolean isDragAndDropEnabled(int position);
        }

        public CoolDragAndDropGridView(Context context) {
                super(context);

                initialize();
        }

        public CoolDragAndDropGridView(Context context, AttributeSet attrs, int defStyle) {
                super(context, attrs, defStyle);

                initialize();
        }

        public CoolDragAndDropGridView(Context context, AttributeSet attrs) {
                super(context, attrs);

                initialize();
        }

        private void initialize() {
                setOnTouchListener(this);
                setChildrenDrawingOrderEnabled(true);
        }

        public void startDragAndDrop() {

                mDragAndDropStarted = true;

        }

        public void setDragAndDropListener(DragAndDropListener dragAndDropListener) {

                mDragAndDropListener = dragAndDropListener;

        }

        private void destroyDragImageView() {

                if (mDragImageView != null) {

                        mWindowManager.removeView(mDragImageView);

                        BitmapDrawable bitmapDrawable = (BitmapDrawable) mDragImageView.getDrawable();
                        if (bitmapDrawable != null) {
                                final Bitmap bitmap = bitmapDrawable.getBitmap();
                                if (bitmap != null && !bitmap.isRecycled()) {
                                        bitmap.recycle();
                                }
                        }

                        mDragImageView.setImageDrawable(null);
                        mDragImageView = null;
                }

        }

        private ImageView createDragImageView(final View v, final int x, final int y) {

                v.destroyDrawingCache();
                v.setDrawingCacheEnabled(true);
                Bitmap bm = Bitmap.createBitmap(v.getDrawingCache());

                mDragPointX = x - v.getLeft();
                mDragPointY = y - v.getTop();

                mWindowParams = new WindowManager.LayoutParams();
                mWindowParams.gravity = Gravity.TOP | Gravity.LEFT;

                mWindowParams.x = x - mDragPointX + mDragOffsetX;
                mWindowParams.y = y - mDragPointY + mDragOffsetY;

                mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
                mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
                mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

                mWindowParams.format = PixelFormat.TRANSLUCENT;
                mWindowParams.alpha = 0.7f;
                mWindowParams.windowAnimations = 0;

                ImageView iv = new ImageView(getContext());
                iv.setBackgroundColor(Color.parseColor("#ff555555"));
                iv.setImageBitmap(bm);

                mWindowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);// "window"
                mWindowManager.addView(iv, mWindowParams);
                return iv;

        }

        private void startDrag(final int x, final int y) {

                final View v = getChildAt(mDragPosition);

                destroyDragImageView();

                mDragImageView = createDragImageView(v, x, y);
                v.setVisibility(View.INVISIBLE);

                if (mDragAndDropListener != null) {

                        mDragAndDropListener.onDragItem(mDragPosition);
                }

        }

        @Override
        protected int getChildDrawingOrder(int childCount, int i) {
                if (mCurrentPosition == -1)
                        return i;
                else if (i == childCount - 1)
                        return mCurrentPosition;
                else if (i >= mCurrentPosition)
                        return i + 1;
                return i;
        }

        private void onDrop() {

                destroyDragImageView();

                removeCallbacks(mDelayedOnDragRunnable);

                View v = getChildAt(mDropPosition);
                v.setVisibility(View.VISIBLE);

                v.clearAnimation();

                if (mDragAndDropListener != null && mDropPosition != AdapterView.INVALID_POSITION) {

                        mDragAndDropListener.onDropItem(mDragPosition, mDropPosition);
                }

                mDragPosition = mDropPosition = mCurrentPosition = AdapterView.INVALID_POSITION;
                mDragAndDropStarted = false;
        }

        public void setScrollingStrategy(ScrollingStrategy scrollingStrategy) {

                mScrollingStrategy = scrollingStrategy;

        }

        private void onDrag(final int x, final int y) {

                if (mScrollingStrategy != null && mScrollingStrategy.performScrolling(x, y, this)) {

                        removeCallbacks(mDelayedOnDragRunnable);

                        return;
                }

                final int tempDropPosition = pointToPosition(mCurrentPosition, x, y);

                if (mDragAndDropListener != null && mDropPosition != tempDropPosition && tempDropPosition != AdapterView.INVALID_POSITION) {

                        removeCallbacks(mDelayedOnDragRunnable);

                        if (mDragAndDropListener.isDragAndDropEnabled(tempDropPosition)) {

                                mDropPosition = tempDropPosition;

                                mDelayedOnDragRunnable = new Runnable() {

                                        @Override
                                        public void run() {

                                                mDragAndDropListener.onDraggingItem(mCurrentPosition, tempDropPosition);
                                                performDragAndDropSwapping(mCurrentPosition, tempDropPosition);

                                                final int nextDropPosition = pointToPosition(tempDropPosition, x, y);

                                                if (nextDropPosition == AdapterView.INVALID_POSITION) {

                                                        mCurrentPosition = mDropPosition = tempDropPosition;

                                                }
                                        }
                                };

                                postDelayed(mDelayedOnDragRunnable, ITEM_HOVER_DELAY);

                        } else {

                                mDropPosition = mDragPosition;

                        }

                }

                if (mDragImageView != null) {

                        mWindowParams.x = x - mDragPointX + mDragOffsetX;
                        mWindowParams.y = y - mDragPointY + mDragOffsetY;
                        mWindowManager.updateViewLayout(mDragImageView, mWindowParams);
                }

        }

        public void setOnTrackTouchEventListener(OnTrackTouchEventsListener onTrackTouchEventsListener) {

                mOnTrackTouchEventsListener = onTrackTouchEventsListener;
        }

        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {

                if (mOnTrackTouchEventsListener != null) {
                        mOnTrackTouchEventsListener.trackTouchEvents(event);
                }

                switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_MOVE:

                        if (mDragAndDropListener != null && mDragAndDropStarted) {

                                mDragAndDropStarted = false;

                                getParent().requestDisallowInterceptTouchEvent(true);

                                return launchDragAndDrop(event);
                        }

                        break;

                default:
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:

                        mDragAndDropStarted = false;

                        getParent().requestDisallowInterceptTouchEvent(false);

                        break;
                }

                return super.onInterceptTouchEvent(event);
        }

        private boolean launchDragAndDrop(final MotionEvent event) {

                final int x = (int) event.getX();
                final int y = (int) event.getY();

                mCurrentPosition = mDragPosition = mDropPosition = pointToPosition(mDragPosition, x, y);

                if (mDragPosition != AdapterView.INVALID_POSITION && mDragAndDropListener.isDragAndDropEnabled(mDragPosition)) {

                        mDragOffsetX = (int) (event.getRawX() - x);
                        mDragOffsetY = (int) (event.getRawY() - y);

                        startDrag(x, y);

                        return true;
                }

                return false;
        }

        @Override
        public boolean onTouch(View view, MotionEvent event) {

                if (mDragPosition != AdapterView.INVALID_POSITION && mDragImageView != null) {

                        final int x = (int) event.getX();
                        final int y = (int) event.getY();

                        switch (event.getAction()) {

                        case MotionEvent.ACTION_MOVE:

                                mDragOffsetX = (int) (event.getRawX() - x);
                                mDragOffsetY = (int) (event.getRawY() - y);

                                onDrag(x, y);

                                break;

                        case MotionEvent.ACTION_UP:
                        case MotionEvent.ACTION_CANCEL:

                                onDrop();

                                resetLongClickTransition();

                                getParent().requestDisallowInterceptTouchEvent(false);

                                return false;

                        default:

                        }

                        return true;
                }

                return false;
        }
}

Sample using this approach of a drag and drop is here

like image 35
user3074632 Avatar answered Nov 15 '22 19:11

user3074632