Android:将项目拖出滚动列表/库

我想实现一个允许用户将项目拖出的Gallery.这不应该妨碍滚动/投掷.

给定界面布局,用户只能在垂直路径中将项目拖出画廊,并水平滚动图库.

这可行吗?有没有一种简单的方法来检测水平移动,并将它们推迟到画廊的事件处理程序,并拦截垂直移动?或者我是否必须重写onInterceptTouchEvent()并自己进行数学运算?

(编辑:我正在尝试使用GestureListener,覆盖onFling和onScroll,并在垂直滚动距离低于阈值时将事件传递给Gallery)

解决方法:

我继承了Gallery,并覆盖了onScroll方法.我还没有实现drop逻辑,但是拖动和滚动工作.

当我可以节省时间时,我会在我的博客中写一篇完整的帖子,其中包含更多细节和丢弃机制.现在,一个简单的复制粘贴,以防将来某人到达此页面.

为了保持它所属的行为,我创建了这个DraggableView接口:

public interface DraggableView {
    public void beforeDrag();

    public DragView createDragView();
    public Object   getDraggedInfo();

    public void afterDrop();
}

如果实现此视图,则可以将“库”中的视图拖出“库”区域.他们会在之前和之后得到通知,并且必须实现两种方法:

> createDragView()返回一个DragView对象.基本上,一个透明的悬停位图伴随着用户的运动.
> getDraggedInfo()返回应该到达放置目标的信息.

这是DragView类:

public class DragView extends ImageView {

    private final LayoutParams  mLayoutParams;

    public DragView(Context context, Bitmap bitmap) {
        super(context);

        mLayoutParams = new LayoutParams();

        mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;

        mLayoutParams.height = LayoutParams.WRAP_CONTENT;
        mLayoutParams.width  = LayoutParams.WRAP_CONTENT;

        mLayoutParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE
                            | LayoutParams.FLAG_NOT_TOUCHABLE;

        mLayoutParams.format = PixelFormat.TRANSLUCENT;
        mLayoutParams.windowAnimations = 0;

        mLayoutParams.alpha = 0.5f;

        setImageBitmap(bitmap);

        setLayoutParams(mLayoutParams);
    }

    public void move(int x, int y) {
        mLayoutParams.x = x;
        mLayoutParams.y = y;
    }
}

如您所见,它构建了一个Bitmap,并创建了一个悬停的ImageView.最后,这里是(刚刚实现的并不是很干净的)Gallery代码,以实现这一切:

public class DraggableItemGallery extends Gallery {

    private boolean mDragging;
    private DragView mDragView;
    private DraggableView mDragViewOwner;

    private WindowManager mWindowManager;

    private boolean mScrollStarted;

    public DraggableItemGallery(Context context) {
        super(context);
        initialize();
    }

    public DraggableItemGallery(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize();
    }

    public DraggableItemGallery(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initialize();
    }

    public void initialize() {
        mWindowManager = (WindowManager)
            getContext().getSystemService("window");
    }

    private void startDraggingItem(DraggableView view, int x, int y) {
        mDragging      = true;
        mDragViewOwner = view;
        mDragView      = view.createDragView();

        mDragView.move(x, y);

        mWindowManager.addView(mDragView, mDragView.getLayoutParams());
    }

    private void continueDraggingItem(int x, int y) {
        DragView dragView = getDragView();

        dragView.move(x, y);
        mWindowManager.updateViewLayout(dragView, dragView.getLayoutParams());
    }

    private void stopDraggingItem() {
        mDragging = false;

        mWindowManager.removeView(mDragView);

        mDragViewOwner.afterDrop();

        mDragView      = null;
        mDragViewOwner = null;
    }

    private DraggableView getDraggedItem() {
        return mDragViewOwner;
    }

    private DragView getDragView() {
        return mDragView;
    }

    private boolean isDraggingItem() {
        return (mDragging);
    }

    private void setScrolling(boolean scrolling) {
        mScrollStarted = scrolling;
        System.out.println("Scrolling " + scrolling);
    }

    private boolean isScrolling() {
        return mScrollStarted;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if ((event.getAction() & ACTION_MASK) == ACTION_UP) {
            setScrolling(false);

            if (isDraggingItem())
                stopDraggingItem();
        }

            return super.onTouchEvent(event);
    }


    final Rect onScroll_tempRect = new Rect();

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        if (isScrolling()) {
            if (isDraggingItem()) {
                int x = (int) e2.getX(),
                    y = (int) e2.getY();

                System.out.println("Moving to " + x + " " + y);

                continueDraggingItem(x, y);
                return true;

            } else {
                /* Not dragging, let the Gallery handle the event */
                return super.onScroll(e1, e2, distanceX, distanceY);
            }

        } else {
            setScrolling(true);
            boolean isVertical = (Math.abs(distanceY) > Math.abs(distanceX));

            if (isVertical) {
                int x = (int) e1.getX(),
                    y = (int) e1.getY();

                View hitChild = null;

                // A tiny optimization, declared above this method
                final Rect hitRect = onScroll_tempRect;

                for (int i = 0; i < getChildCount(); i++) {
                    View child = getChildAt(i);
                    child.getHitRect(hitRect);

                    if (hitRect.contains(x, y)) {
                        hitChild = child;
                        break;
                    }
                }

                if (hitChild instanceof DraggableView) {
                    startDraggingItem((DraggableView) hitChild, x, y);
                    return true;
                }
            }

            /* Either the scroll is not vertical, or the point
             * of origin is not above a DraggableView. Again,
             * we let the Gallery handle the event.
             */
            return super.onScroll(e1, e2, distanceX, distanceY);
        }
    }
}

希望能帮助到你.

上一篇:带有标题的Android图库


下一篇:java – 重用默认的Android图片库?