在Android中的GridView中拖放

如何在Android GridView中实现拖放function。 任何人都可以提供同样的最好的链接?

Solutions Collecting From Web of "在Android中的GridView中拖放"

请参阅PagedDragDropGrid

上面的例子已经实现了使用ViewGroup 拖放可移动项目的分页网格。

注@ 它支持Android 2.2(API 8)及以上版本。

这是我见过的android拖放android 2.2中最好的例子。 你使用了哪个版本?

你可以在这里find关于拖放的谷歌文档和第三方的例子。

你要做的是将你的gridView中的每个视图设置为可点击并设置onTouchListener。 在你的onTouch方法中,你将为ACTION_DOWN(用户在屏幕上按下),ACTION_MOVE(用户在屏幕上移动手指)和ACTION_UP(用户从屏幕上抬起手指)处理适当的动作。

尝试使用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; } } 

使用这种拖放方法的示例在这里

最好的办法是扩展标准的Gridview控件,因为你可以将它与其他标准代码(如用于适配器或数据结构的标准代码(也对Listviews通用))集成。 您需要确定需要拖动的项目(可能需要长时间点击),然后隐藏源视图,然后绘制覆盖位图副本,随着用户保持手指向下,将在屏幕上移动。 在触摸的时候,你会看到你的拖动源已经被删除了,或者你将它移动到那里,或者删除它(如果在Android主屏幕的gridview中删除了一个删除区域)。 自定义gridview拖放示例

作为进入更多细节的一个很好的链接,我会推荐一篇我最近写的文章,解释所有内容,并提供开源项目代码。 链接是: http : //www.pocketmagic.net/2013/11/complex-android-gridview-with-drag-and-drop-functionality/也可在谷歌代码: http : //code.google.com / p /机器人-gridview的拖动和放下/

在YouTube上观看演示video: http : //www.youtube.com/watch?v = m4yktX3SWSs

希望这可以帮助!