What I want to achieve:
I want to create a drag and drop function in Android. I would like to use a specific layout (different from the drag object itself) as a drop shadow.
What result do I get instead:
None of my approaches work as expected - in the end I donβt have a visible shadow shadow (although the target gets dropped).
What I tried:
I tried
- inflating the
drag_item layout in activity and then passing it as an argument to the shadow builder constructor
and
- inflating the
drag_item layout in the drag_item shadow builder onDrawShadow and then drawing it on canvas
Layouts
My activity layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.app.DragDropTestActivity" tools:ignore="MergeRootFrame"> <TextView android:id="@+id/tvReceiver" android:text="Drop here" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:id="@+id/btnDragged" android:layout_height="wrap_content" android:text="Drag me" android:layout_width="match_parent"/> </LinearLayout>
The layout I want to use as the shadow shadow:
dragged_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Dragged Item"/> </LinearLayout>
Source:
Here's the code with both approaches (represented by 1 , BuilderOne and 2 , BuilderTwo , respectively):
package com.example.app; import android.graphics.Canvas; import android.graphics.Point; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.widget.Button; public class DragDropTestActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_drag_drop_test); Button dragged = (Button) findViewById(R.id.btnDragged); dragged.setOnTouchListener( new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() != MotionEvent.ACTION_DOWN) { return false; } LayoutInflater inflater = getLayoutInflater(); int approach = 1;
My BuilderOne class:
public static class BuilderOne extends View.DragShadowBuilder { public BuilderOne(View view) { super(view); } @Override public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) { super.onProvideShadowMetrics( shadowSize, shadowTouchPoint); } }
And the BuilderTwo class:
public static class BuilderTwo extends View.DragShadowBuilder { final LayoutInflater inflater; public BuilderTwo(LayoutInflater inflater, View view) { super(view); this.inflater = inflater; } @Override public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) { super.onProvideShadowMetrics( shadowSize, shadowTouchPoint); } @Override public void onDrawShadow(Canvas canvas) { final View draggedItem = inflater.inflate(R.layout.dragged_item, null); if (draggedItem != null) { draggedItem.draw(canvas); } } } }
Question:
What am I doing wrong?
Update:
Added bounty.
android drag-and-drop
Konrad Morawski
source share