Mover, Rotar y hacer Zoom a ImageView

En este tutorial veremos cómo ampliar, mover y rotar un ImageView.

Este tutorial requiere de conocimiento mínimo de como hacer una app simple de Android, si conoces este tema y un poco de ello, puedes continuar…

Esto no es sólo para ImageView, se puede hacer uso del mismo código para Button, TextView, etc; simplemente cambiando la referencia del ObjectID.

Necesitamos agregar un onTouchListener al ImageView para realizar todas estas operaciones.

Comencemos agregando el ImageView a nuestro layout.xml

[java]<ImageView
android:src="@drawable/zimbronapps"
android:layout_width="150dp"
android:layout_height="150dp"
android:id="@+id/imagen_movil"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"/>[/java]

Teniendo agregado nuestro ImageView, en este caso hemos puesto el id del view con el nombre: zimbronapps, vamos al archivo MainActivity.java suponiendo que el ImageView está creado en el layout prncipal (activity_main.xml).

Importaremos las siquientes librerías:
[java]import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;[/java]

Paso siguiente: Creamos las variables necesarias, justo entre donde empieza la clase MainActivity y donde empieza el método onCreate
[java highlight=»3-11″]public class MainActivity extends AppCompatActivity {

ImageView imagen_movible;
float escaladiff;
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int modo = NONE;
private float oldDist = 1f;
private float d = 0f;
private float newRot = 0f;

@Override
protected void onCreate(Bundle savedInstanceState) {[/java]

Justo después de init(); instanciaremos las variables y recuperaremos los views del layout
[java highlight=»7-12″] @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

init();
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(250, 250);
layoutParams.leftMargin = 50;
layoutParams.topMargin = 50;
layoutParams.bottomMargin = 250;
layoutParams.rightMargin = 250;
imagen_movible.setLayoutParams(layoutParams);[/java]

creamos el onTouchListener enseguida y los metodos necesarios para obtener la posicion del ImageView, no explicaré a fondo cada uno de los métodos, pero dejaré un enlace a la referencia en Android para que vean como funciona, el MainActivity.java les quedará de la siguiente manera (el nombre del paquete será el nombre del paquete de tu app)

[java]package com.zimbronapps.prueba;

import android.graphics.drawable.BitmapDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;

public class MainActivity extends AppCompatActivity {

ImageView imagen_movible;
float escaladiff;
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int modo = NONE;
private float oldDist = 1f;
private float d = 0f;
private float newRot = 0f;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

init();
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(250, 250);
layoutParams.leftMargin = 50;
layoutParams.topMargin = 50;
layoutParams.bottomMargin = 250;
layoutParams.rightMargin = 250;
imagen_movible.setLayoutParams(layoutParams);

imagen_movible.setOnTouchListener(new View.OnTouchListener() {
RelativeLayout.LayoutParams params;
int startwith;
int startheight;
float dx = 0, dy = 0, x = 0, y = 0;
float angle = 0;

@Override
public boolean onTouch(View v, MotionEvent event) {
final ImageView view = (ImageView) v;

((BitmapDrawable) view.getDrawable()).setAntiAlias(true);

switch (event.getAction() & MotionEvent.ACTION_MASK) {

case MotionEvent.ACTION_DOWN:
params = (RelativeLayout.LayoutParams) view.getLayoutParams();
startwith = params.width;
startheight = params.height;
dx = event.getRawX() – params.leftMargin;
dy = event.getRawY() – params.topMargin;
modo = DRAG;
break;

case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if(oldDist > 10f){
modo = ZOOM;
}

d = rotation(event);

break;

case MotionEvent.ACTION_POINTER_UP:
modo = NONE;
break;

case MotionEvent.ACTION_MOVE:
if(modo == DRAG){

x = event.getRawX();
y = event.getRawY();

params.leftMargin = (int) (x – dx);
params.topMargin = (int) (y – dy);

params.bottomMargin = 0;
params.rightMargin = 0;

params.rightMargin = params.leftMargin + (5 * params.width);
params.bottomMargin = params.topMargin + (10 * params.height);

view.setLayoutParams(params);
}else if(modo == ZOOM){
if(event.getPointerCount() == 2){
newRot = rotation(event);
float r = newRot – d;
angle = r;

x = event.getRawX();
y = event.getRawY();

float newDist = spacing(event);
if(newDist > 10f){
float escala = newDist / oldDist * view.getScaleX();
if(escala > .5){
escaladiff = escala;
view.setScaleX(escala);
view.setScaleY(escala);
}
}

view.animate().rotationBy(angle).setDuration(0).setInterpolator(new LinearInterpolator()).start();

params.leftMargin = (int) ((x – dx) + escaladiff);
params.topMargin = (int) ((y – dy) + escaladiff);

params.rightMargin = 0;
params.bottomMargin = 0;
params.rightMargin = params.leftMargin + (5 * params.width);
params.bottomMargin = params.topMargin + (10 * params.height);

view.setLayoutParams(params);
}
}
break;
}

return true;
}
});

}

private void init() {
imagen_movible = (ImageView) findViewById(R.id.imagen_movil);
}

private float spacing(MotionEvent event) {
float x = event.getX() – event.getX(1);
float y = event.getY() – event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}

private float rotation(MotionEvent event) {
double delta_x = (event.getX(0) – event.getX(1));
double delta_y = (event.getY(0) – event.getY(1));
double radianes = Math.atan2(delta_y,delta_x);

return (float) Math.toDegrees(radianes);
}
}
[/java]

Referencias de las funciones:

Si hiciste todo correctamente tendrás un resultado mas o menos así:

para descargar el proyecto de este tutorial y lo pruebes tu mismo haz clic en el siguiente botón:

Si te sirvió, no olvides darle like y compartirlo!

Sobre Gustavo Zimbrón 188 artículos
Apasionado por la programación y la tecnología, me gustan los retos y aprender siempre cosas nuevas.
Subscribe
Notify of
guest

3 Comentarios
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Andy

Hola quisiera saber como puedo hacer para que la imagenview al momento de arrastrarla con el dedo esta imagen se copie y no se mueva la original y desplazarla la copia aun lugar especifico, sin que se vaya a otro lado. y otra de como hacer para que moviéndola a otro lugar especifico dentro del mismo activity esta se haga mas pequeña

Andy

bien, puede ser, pero si quiero sacar varias, en el caso de una suma, tengo los 10 números en imageview, cuando lleve dos números o 3 números, es buena tu respuesta, pero no perjudica a la memoria??
y si la imagen la querría hacer mas pequeña cuando se copie???