Estaba jugando con el fab en la biblioteca de diseño de soporte cuando ejecuté este problema. Reemplacé el método onCreate en la plantilla de Actividad en blanco predeterminada en Android Studio, así es como se ve:

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.animation.TranslateAnimation;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                TranslateAnimation anim = new TranslateAnimation(0, -500, 0, -500);
                anim.setDuration(1000);
                anim.setFillEnabled(true);
                anim.setFillAfter(true);
                fab.startAnimation(anim);
            }
        });
        fab.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                TranslateAnimation anim = new TranslateAnimation(0, -500, 0, -500);
                anim.setDuration(1000);
                anim.setFillEnabled(true);
                anim.setFillAfter(true);
                fab.startAnimation(anim);
                return true;
            }
        });
    }
}

Básicamente, agregué un onClickListener y un onLongClickListener que traducen el fab en 500idks, pero el problema es que no funciona como se supone que debe hacerlo.

Cuando hago clic en él, normalmente no sucede nada, lo cual es extraño para empezar. Aquí hay un video de cómo está sucediendo.

Cuando lo presiono durante mucho tiempo, se anima como debería, pero solo si sigo presionando, y cada vez que levanto el dedo, vuelve a la posición original, independientemente de si la animación está completa o no, aunque configuré setFillEnabled(true) y setFillAfter(true).

Aquí hay videos de lo que sucede cuando levanto mi dedo y cuando dejar mi dedo en la pantalla hasta el final y todo.

Animation

¿Por qué está pasando esto?

13
Olumide 27 ene. 2016 a las 22:22

5 respuestas

La mejor respuesta

No sé por qué tiene este problema de animación, pero parece un error. Revisé su código y funciona en mi Android 6.0, pero no funciona en el emulador de Android con Android 4.4 integrado (pero mi problema es un poco diferente al suyo).

Supongo que es un error, porque TranslateAnimation tenía (y tal vez todavía tiene) algunos errores como este one, dos.

Y mi sugerencia de cómo evitarlo es la siguiente. Utilice ViewPropertyAnimator para animar sus vistas. Y su código en este caso debería verse así:

    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            fab.animate()
                    .translationX(-500)
                    .translationY(-500)
                    .setDuration(1000)
                    .start();
        }
    });
    fab.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View view) {
            fab.animate()
                    .translationX(-500)
                    .translationY(-500)
                    .setDuration(1000)
                    .start();
            return true;
        }
    });

Lo verifiqué en el emulador de Android con Android 4.3, 4.4, 5.0, 6.0 y funciona bien.

Actualizar

Solución encontrada para ti. Entonces puede usar ViewPropertyAnimatorCompat de la biblioteca de soporte y su código sería similar a:

fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
            ViewCompat.animate(fab)
                    .translationX(-500)
                    .translationY(-500)
                    .setDuration(1000)
                    .start();
    }
});
fab.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View view) {
            ViewCompat.animate(fab)
                    .translationX(-500)
                    .translationY(-500)
                    .setDuration(1000)
                    .start();
        return true;
    }
});
6
Igor Tyulkanov 4 feb. 2016 a las 09:21

Necesita usar ViewPropertyAnimator para que esto funcione. La animación en realidad no mueve la vista en sí, solo una representación de mapa de bits de la vista, como se describe aquí.

1
Community 23 may. 2017 a las 12:01

Tal vez esto se relacione con su problema: SO-Thread

Estoy usando un AnimatorListener para establecer la posición de una vista después de una animación terminada.

.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            // set Position
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });

Solo veo un extracto de tu código. Para su problema con onClickListener, comprobaría si ha configurado android: clickable = "false" dentro de su xml o si ha implementado otro OnClickListener.

1
Community 23 may. 2017 a las 11:53

Creo que debe mantener el objeto anim como una variable de nivel de clase, onLongClick () y onClick () se llaman de manera superpuesta en muchos casos. Dado que tienes diferentes objetos de animación, terminas accediendo al mismo fab desde dos objetos de animación.

Mantenga anim afuera y publique su observación por favor.

E intente eliminar los métodos onLongClick () o onClick (). si es posible, agregue el registro en esos dos métodos para comprender la secuencia de llamadas.

Estaré esperando tus observaciones.

2
Karthik Kumar 2 feb. 2016 a las 14:10

Actualización : ahora se supone que se solucionará en la versión de soporte 24.2.0 después del error que abrí: https://code.google.com/p/android/issues/detail?id=215043

==============

Para aquellos de nosotros que no tenemos la suerte de reemplazar su animación con una ViewPropertyAnimation como yo:

Este error ocurre debido a un error en la implementación de soporte del FloatingActionButton, específico en FloatingActionButtonEclairMr1 clase, donde se configura la animación para todos los estados de vista, por lo que al hacer clic en la vista hay una animación FloatingActionButtonEclairMr1.ElevateToTranslationZAnimation que se activa, por lo que su animación se borra de la vista.

La solución más simple que he encontrado es comenzar la animación con un poco de retraso, NO con startOffset (porque la animación de presionar aún la anulará) pero llamando a la animación con retraso (estoy usando 100, pero también verifico con 60 y funcionó. 20 no es suficiente):

    final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //Probably want to do it just for pre Lolipop
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    TranslateAnimation anim = new TranslateAnimation(0, -500, 0, -500);
                    anim.setDuration(1000);
                    anim.setFillEnabled(true);
                    anim.setFillAfter(true);
                    fab.startAnimation(anim);
                }
            }, 100);
        }
    });
    fab.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View view) {
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    TranslateAnimation anim = new TranslateAnimation(0, -500, 0, -500);
                    anim.setDuration(1000);
                    anim.setFillEnabled(true);
                    anim.setFillAfter(true);
                    fab.startAnimation(anim);
                }
            }, 100);
        }
    });
3
shem 18 ago. 2016 a las 06:52