Drag and Drop in GridView on Android

How can I implement the drag and drop feature in Android GridView. Can anyone provide a better link for this?

+7
source share
5 answers

see PagedDragDropGrid

The above example implements a mesh with moving drag'n'drop elements using a ViewGroup.

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

+6
source

You can find the Google drag and drop documentation here and an example of a third party.

What you need to do is set each view in your gridView for clickability and install onTouchListener. In your onTouch method, you then process the corresponding actions for ACTION_DOWN (the user clicked on the screen), ACTION_MOVE (the user moves his finger on the screen) and ACTION_UP (the user lifts a finger from the screen).

+1
source

Try a different approach 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; } } 

An example using this drag method here

+1
source

The best way is to extend the standard Gridview control, as you can integrate it with other standard code, for example, adapters or data structures (also common for Listviews, etc.). You will need to identify the item to be dragged, possibly with a long click, then hide the source view and draw an overlay bitmap that will move around the screen when the user holds his finger down. When you touch, you see where the drag and drop source was disabled, and either you move it there, or delete it (if it fell over the delete zone, for example, in the form of a grid in the Android main screen). custom gridview with drag and drop example

As a good reference for more details, I would recommend an article I recently wrote explaining everything and also providing open source project code. Link: http://www.pocketmagic.net/2013/11/complex-android-gridview-with-drag-and-drop-functionality/ Also available in google code at: http://code.google.com/ p / android-gridview-drag-and-drop /

YouTube demo video: http://www.youtube.com/watch?v=m4yktX3SWSs

Hope this helps!

0
source

All Articles