The following code shows how to React to long-press listener.
Code revised from
Android Recipes:A Problem-Solution Approach
http://www.apress.com/9781430234135
ISBN13: 978-1-4302-3413-5
Main layout xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- Top Row of Draggable Items --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <ImageView android:id="@+id/image1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:src="@drawable/ic_launcher" /> <ImageView android:id="@+id/image2" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:src="@drawable/ic_launcher" /> <ImageView android:id="@+id/image3" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:src="@drawable/ic_launcher" /> </LinearLayout> <!-- Bottom Row of Drop Targets --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:orientation="horizontal" > <com.examples.dragtouch.DropTargetView android:id="@+id/drag_target1" android:layout_width="0dp" android:layout_height="100dp" android:layout_weight="1" android:background="#A00" /> <com.examples.dragtouch.DropTargetView android:id="@+id/drag_target2" android:layout_width="0dp" android:layout_height="100dp" android:layout_weight="1" android:background="#0A0" /> <com.examples.dragtouch.DropTargetView android:id="@+id/drag_target3" android:layout_width="0dp" android:layout_height="100dp" android:layout_weight="1" android:background="#00A" /> </LinearLayout> </RelativeLayout>
Main activity Java code
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.DragShadowBuilder; import android.view.View.OnLongClickListener; import android.widget.ImageView; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.view.View; import android.view.View.DragShadowBuilder; public class MainActivity extends Activity implements OnLongClickListener { //from w ww . jav a 2 s .c o m @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //Attach long-press listener to each ImageView findViewById(R.id.image1).setOnLongClickListener(this); findViewById(R.id.image2).setOnLongClickListener(this); findViewById(R.id.image3).setOnLongClickListener(this); } @Override public boolean onLongClick(View v) { DragShadowBuilder shadowBuilder = new DragShadowBuilder(v); // DragShadowBuilder shadowBuilder = new DrawableDragShadowBuilder(v, // getResources().getDrawable(R.drawable.ic_launcher)); v.startDrag(null, shadowBuilder, ((ImageView) v).getDrawable(), 0); return true; } } /* * Copyright (C) 2011 by Mark Doffman * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE */ class DrawableDragShadowBuilder extends DragShadowBuilder { private Drawable mDrawable; public DrawableDragShadowBuilder(View view, Drawable drawable) { super(view); // Set the drawable and apply a green filter to it mDrawable = drawable; mDrawable.setColorFilter(new PorterDuffColorFilter(Color.GREEN, PorterDuff.Mode.MULTIPLY)); } @Override public void onProvideShadowMetrics(Point shadowSize, Point touchPoint) { // Fill in the size shadowSize.x = mDrawable.getIntrinsicWidth(); shadowSize.y = mDrawable.getIntrinsicHeight(); // Fill in the location of the shadow relative to the touch. // Here we center the shadow under the finger. touchPoint.x = mDrawable.getIntrinsicWidth() / 2; touchPoint.y = mDrawable.getIntrinsicHeight() / 2; mDrawable.setBounds(new Rect(0, 0, shadowSize.x, shadowSize.y)); } @Override public void onDrawShadow(Canvas canvas) { //Draw the shadow view onto the provided canvas mDrawable.draw(canvas); } }
custom view java code
/* ww w .j a va 2 s. c om*/ import android.animation.Keyframe; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.content.Context; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.DragEvent; import android.view.View.OnDragListener; import android.widget.ImageView; public class DropTargetView extends ImageView implements OnDragListener { private boolean mDropped; public DropTargetView(Context context) { super(context); init(); } public DropTargetView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public DropTargetView(Context context, AttributeSet attrs, int defaultStyle) { super(context, attrs, defaultStyle); init(); } private void init() { //We must set a valid listener to receive DragEvents setOnDragListener(this); } @Override public boolean onDrag(android.view.View v, DragEvent event) { PropertyValuesHolder pvhX, pvhY; switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: //React to a new drag by shrinking the view pvhX = PropertyValuesHolder.ofFloat("scaleX", 0.5f); pvhY = PropertyValuesHolder.ofFloat("scaleY", 0.5f); ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY).start(); //Clear the current drop image on a new event setImageDrawable(null); mDropped = false; break; case DragEvent.ACTION_DRAG_ENDED: // React to a drag ending by resetting the view size // if we weren't the drop target. if (!mDropped) { pvhX = PropertyValuesHolder.ofFloat("scaleX", 1f); pvhY = PropertyValuesHolder.ofFloat("scaleY", 1f); ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY).start(); mDropped = false; } break; case DragEvent.ACTION_DRAG_ENTERED: //React to a drag entering this view by growing slightly pvhX = PropertyValuesHolder.ofFloat("scaleX", 0.75f); pvhY = PropertyValuesHolder.ofFloat("scaleY", 0.75f); ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY).start(); break; case DragEvent.ACTION_DRAG_EXITED: //React to a drag leaving this view by returning to previous size pvhX = PropertyValuesHolder.ofFloat("scaleX", 0.5f); pvhY = PropertyValuesHolder.ofFloat("scaleY", 0.5f); ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY).start(); break; case DragEvent.ACTION_DROP: // React to a drop event with a short animation keyframe animation // and setting this view's image to the drawable passed along with // the drag event // This animation shrinks the view briefly down to nothing // and then back. Keyframe frame0 = Keyframe.ofFloat(0f, 0.75f); Keyframe frame1 = Keyframe.ofFloat(0.5f, 0f); Keyframe frame2 = Keyframe.ofFloat(1f, 0.75f); pvhX = PropertyValuesHolder.ofKeyframe("scaleX", frame0, frame1, frame2); pvhY = PropertyValuesHolder.ofKeyframe("scaleY", frame0, frame1, frame2); ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY).start(); //Set our image from the Object passed with the DragEvent setImageDrawable((Drawable) event.getLocalState()); //We set the dropped flag to the ENDED animation will not also run mDropped = true; break; default: //Ignore events we aren't interested in return false; } //Declare interest in all events we have noted return true; } }