8

如何在 Android GridView 中实现拖放功能。任何人都可以请提供相同的最佳链接吗?

4

4 回答 4

6

PagedDragDropGrid

上面的示例使用 ViewGroup 实现了一个带有拖放可移动项目的分页网格。

注意@它支持 Android 2.2 (API 8) 及更高版本。

于 2012-12-31T12:31:52.240 回答
3

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

于 2012-10-02T12:50:16.250 回答
1

您可以在此处找到有关拖放的 google 文档,并在此处找到第三方示例。

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

于 2012-10-02T12:55:35.937 回答
1

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

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

于 2013-12-10T06:34:21.367 回答