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

<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"/>

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:

import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;

Paso siguiente: Creamos las variables necesarias, justo entre donde empieza la clase MainActivity y donde empieza el método onCreate

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) {

Justo después de init(); instanciaremos las variables y recuperaremos los views del layout

          @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);

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)

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);
    }
}

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 61 Artículos
Me apasiona la programación, los video juegos, viajar, la naturaleza, salir de party. Estoy inmerso en el mundo de la programación desde los 16 años, mas sin embargo, nunca se deja de aprender en este mundo. Trato de aprender algo nuevo cada día.

3 Comentarios

  1. 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

Dejar una contestacion

Tu dirección de correo electrónico no será publicada.


*