Reputation: 2287
I have a gridview that I need to implement drag and drop feature. I've been trying to find a possible solution or existing library that would fit my problem but still no luck.
Here's a before and after illustration of the drag and drop that I need to implement:
The red tiles are items wherein they cannot be dragged nor dropped on. the blue ones are draggable and can be dropped on any tile on any row, just not on the red tiles. The white tiles are just placeholders which are placed to have the red tiles on the first column.
Now, when tile A is dragged on the 3rd row, as you can see, they go side by side, not swapped, even if put on top of tile C. The number of white tiles is depending on the number of blue tiles per row, an arraylist is assigned on each row, so it'll just follow. My real problem is that all examples on gridview drag and drop is that tiles swaps or the whole grid follows the flow of items.
My plan to implement this:
Here's breaking down the problem to slightly smaller problems:
Upvotes: 0
Views: 1404
Reputation: 2287
I ended up editting http://code.google.com/p/android-gridview-drag-and-drop/ to fit my problem.
Upvotes: 0
Reputation: 47
1.How can I make a larger tile of the long pressed tile? yes,you can get the tile's view and create a new bitmap,the add the bitmap to Windows.Like this : it's a class extends 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.Is it possible to get the position where the enlarged tile is dropped? If your class is extends GridView or AbsListView,this API `pointToPosition(x, y) will return the position of the whole view.
Upvotes: 3
Reputation: 47
When you drop tile A,then you calculate where tile A is now,if above tile C,then start a Animation(C move to side and A take place position of C) and update the Adapter end of the Animation.
Upvotes: 0