I have a requirement where a draggable view needs the shadow to be initially placed directly on top of the view - that is, it covers the entire view rather than relating to the touch point.
I've been trying all sorts to get this working with my subclass of View.DragShadowBuilder
but with no luck. I hoped using drawRect
would allow me to specify the rectangle points so that it would be drawn in the same rectangle as my view, but this results in no canvas being drawn.
However, just using canvas.drawColor(Color.CYAN)
draws the rectangle, but relative to the touch point.
Here is my attempt using drawRect
:
private class VideoDragShadowBuilder extends View.DragShadowBuilder {
public VideoDragShadowBuilder(View v) {
super(v);
}
@Override
public void onProvideShadowMetrics (Point size, Point touch) {
int width, height;
width = getView().getWidth();
height = getView().getHeight();
size.set(width, height);
touch.set(width / 2, height / 2);
}
@Override
public void onDrawShadow(Canvas canvas) {
//canvas.drawColor(Color.CYAN);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setAlpha(45);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.CYAN);
canvas.drawRect(getView().getLeft(), getView().getTop(), getView().getRight(), getView().getBottom(), paint);
}
}
Here, the blue rectangle is slightly misaligned with the view underneath because of where I touched - I want it to totally cover the view regardless of where the user touches.
Here's the solution I ended up with using @pskink's suggestions. I didn't have to use drawRect at all, the key was setting the touch point which I previously didn't have as I wasn't using onTouchEvent. Adding this for anyone who might have the same problem.
private Point lastTouch;
public DraggableFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
dragListener = new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
View.DragShadowBuilder videoShadow = new DragShadowBuilder(v);
v.startDrag(draggableData, videoShadow, null, 0);
return true;
}
};
}
@Override
public boolean onTouchEvent (MotionEvent ev) {
lastTouch = new Point((int) ev.getX(), (int) ev.getY()) ;
return super.onTouchEvent(ev);
}
private class DragShadowBuilder extends View.DragShadowBuilder {
public VideoDragShadowBuilder(View v) {
super(v);
}
@Override
public void onProvideShadowMetrics (Point size, Point touch) {
super.onProvideShadowMetrics(size, touch);
// The touch point must be set in order for the canvas to properly fit the view
if (lastTouch != null) {
touch.set(lastTouch.x, lastTouch.y);
}
}
@Override
public void onDrawShadow(Canvas canvas) {
super.onDrawShadow(canvas);
canvas.drawColor(Color.CYAN);
}
}