Android GridView自定义拖放

时间:2014-09-18 02:09:03

标签: android gridview drag-and-drop android-gridview

我有一个gridview,我需要实现拖放功能。我一直在努力找到一个可能适合我的问题的解决方案或现有的库,但仍然没有运气。

这是我需要实现的拖放的前后插图:

enter image description here

红色瓷砖是不能拖动或掉落的物品。蓝色的是可拖动的,可以放在任何一行的任何瓷砖上,而不是放在红色瓷砖上。白色瓷砖只是放置在第一列上的红色瓷砖的占位符。

现在,当你看到第三行拖动瓷砖A时,它们会并排,而不是交换,即使放在瓷砖C的顶部。白色瓷砖的数量取决于蓝色的数量每行瓷砖,每行分配一个arraylist,所以它只会跟随。我真正的问题是,gridview拖放的所有示例都是tile交换或整个网格跟随项目流。

我计划实施这个:

  1. 当长时间按下要拖动的图块时,它会显示一个看起来像该图块的图块,只有更大和更小的不透明度。
  2. 当放在某个位置时,将计算该行。
  3. 调整arraylists和notifydatasetchanged。
  4. 这里将问题分解为稍小的问题:

    1. 如何制作长按瓷砖的较大瓷砖?
    2. 是否可以获得放大的瓷砖掉落的位置?

3 个答案:

答案 0 :(得分:3)

1.如何制作长按瓷砖的较大瓷砖?是的,您可以获取瓷砖的视图并创建新的位图,将位图添加到Windows。就像这样:它是一个类扩展了GridView。

public boolean setOnItemLongClickListener(final MotionEvent ev)
{
    this.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
    {
        @Override
        public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
                int arg2, long arg3)
        {
            // onInterceptTouchEvent(ev);
            // TODO Auto-generated method stub
            L.l("============on Long Click=========");
            L.l("============X:" + ev.getX() + " Y:" + ev.getY());

            int x = (int) ev.getX();
            int y = (int) ev.getY();
            dragPosition = dropPosition = pointToPosition(x, y);
            System.out.println(dragPosition);
            if (dragPosition == AdapterView.INVALID_POSITION)
            {

            }
            ViewGroup itemView = (ViewGroup) getChildAt(dragPosition
                    - getFirstVisiblePosition());

            dragPointX = x - itemView.getLeft();
            dragPointY = y - itemView.getTop();

            dragOffsetX = (int) (ev.getRawX() - x);
            dragOffsetY = (int) (ev.getRawY() - y);

            itemHeight=itemView.getHeight();

            L.l("========================y:" + y + " getRawY:"
                    + ev.getRawY());


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

            startDrag(bm, x, y);
            return false;
        };
    });
    return super.onInterceptTouchEvent(ev);
}

    private void startDrag(Bitmap bm, int x, int y)
{

    windowParams = new WindowManager.LayoutParams();
    windowParams.gravity = Gravity.TOP | Gravity.LEFT;// 这个必须加
    windowParams.x = x - dragPointX + dragOffsetX;
    windowParams.y = y - dragPointY + dragOffsetY;

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

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

    ImageView iv = new ImageView(getContext());
    iv.setImageBitmap(bm);
    windowManager = (WindowManager) getContext().getSystemService(
            Context.WINDOW_SERVICE);// "window"
    windowManager.addView(iv, windowParams);
    dragImageView = iv;
}


    @Override
public boolean onTouchEvent(MotionEvent ev)
{
    if (dragImageView != null
            && dragPosition != AdapterView.INVALID_POSITION)
    {
        int x = (int) ev.getX();
        int y = (int) ev.getY();
        switch (ev.getAction())
        {
            case MotionEvent.ACTION_MOVE:
                onDrag(x, y);
                break;
            case MotionEvent.ACTION_UP:
                stopDrag();
                onDrop(x, y);
                break;
        }
    }
    return super.onTouchEvent(ev);
}

private void onDrag(int x, int y)
{
    if (dragImageView != null)
    {
        windowParams.alpha = 0.6f;
        windowParams.x = x - dragPointX + dragOffsetX;
        windowParams.y = y - dragPointY + dragOffsetY;
        // L.l("=================windowParams.y=====000========"+windowParams.y);
        windowManager.updateViewLayout(dragImageView, windowParams);
    }

    int tempScrollX = x - dragPointX + dragOffsetX;
    int tempScrollY = y - dragPointY + dragOffsetY;

    if (tempScrollY +itemHeight> 600)
    {
        this.scrollTo(0, tempScrollY);
    }
    else
        if (pointToPosition(x, y) > 2)
        {

            this.scrollTo(0, tempScrollY - 300);
        }

}

2.是否可以获得放大的图块放置的位置? 如果你的类是扩展GridView或AbsListView,这个API`pointToPosition(x,y)将返回整个视图的位置。

答案 1 :(得分:0)

当您删除切片A时,则计算切片A的位置,如果在切片C上方,则启动动画(C移动到C侧的A和A位置)并更新动画的适配器端。 / p>

答案 2 :(得分:0)

我最终编辑http://code.google.com/p/android-gridview-drag-and-drop/以解决我的问题。