React to long-press listener
Description
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
Example
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 ww w.j a va 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
/*w w w. j av a 2 s . c o m*/
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;
}
}