2016-01-27 12 views
13

Grałem z fab w bibliotece projektowania wsparcia, kiedy uruchomiłem inti w tym wydaniu. Wymieniłem onCreate metodę w szablonie domyślnym Blank działalność w Android Studio, to jak to wygląda:Floating Action Button animation Issue

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

Więc zasadniczo I dodaje onClickListener oraz onLongClickListener że przełoży się Fab 500idks, ale problem jest to, że nie działa tak, jak powinno.

Kiedy klikam, normalnie nic się nie dzieje, co jest dziwne na początek. Oto dzieje się video.

Po długim naciśnięciu na nią animuje się tak, jak powinienem, ale tylko jeśli będę naciskać, a kiedy podniosę palec, wróci do pierwotnej pozycji, niezależnie od tego, czy animacja jest kompletna, czy nie, mimo że ustawiłem setFillEnabled(true) i setFillAfter(true).

Oto filmy z tego, co się dzieje, gdy I lift mój palec i kiedy leave mój palec na ekranie do końca i everything.

Animation

Dlaczego tak się dzieje?

+0

myślę, że należy zadeklarować 'FloatingActionButton fab' jest to zmienne globalne –

+0

@MrNeo to nie popełniła różnica – Olumide

+1

i wypróbowałem to na Nexus 4, w wersji 5.1.1. Działa zgodnie z oczekiwaniami i nie ma problemów z konfiguracją. –

Odpowiedz

6

Nie wiem, dlaczego pojawia się ten problem z animacją, ale wygląda na błąd. Sprawdziłem twój kod i działa on na moim Androidzie 6.0, ale nie działa na emulatorze Androida z Androidem 4.4 na pokładzie (ale mój problem jest trochę inny niż twój).

Więc moje założenie to błąd, ponieważ TranslateAnimation miał (i może nadal ma) niektóre błędy takie jak ten one, two.

Moja sugestia, w jaki sposób można tego uniknąć, jest następna. Użyj ViewPropertyAnimator, aby animować swoje widoki. A kod w tym przypadku powinna wyglądać następująco:

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

sprawdziłem go na Android Emulator z Android 4.3, 4.4, 5.0, 6.0 i działa dobrze.

Aktualizacja

Znaleziono rozwiązanie dla Ciebie. Dzięki czemu można korzystać z biblioteki ViewPropertyAnimatorCompat wsparcia i Twój kod będzie podobny do:

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

Yeah ViewPropertyAnimator działa również na moim urządzeniu, ale chciałem coś, co działało z api 11, a ViewPropertyAnimator zostało wprowadzone w 12. Wygląda na to, że możesz mieć rację co do tego błędu. – Olumide

+0

@Olumide, in w takim przypadku możesz spróbować użyć tej biblioteki https://github.com/JakeWharton/NineOldAndroids –

+0

@Olumide, znalazłeś rozwiązanie dla ciebie, zobacz moją zaktualizowaną odpowiedź –

1

Może to dotyczy twojego problemu: SO-Thread

Używam AnimatorListener ustawić pozycję widoku po gotowej animacji.

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

     } 
    }); 

Widzę tylko fragment twojego kodu. Dla twojego problemu z onClickListener chciałbym sprawdzić czy ustawiłeś android: clickable = "false" wewnątrz twojego xml lub jeśli zaimplementowałeś inny OnClickListener.

+0

Podany link był wnikliwy, ale nie wyjaśnia, dlaczego animacja jest tak szybka, jak tylko podniosę palec. Zaktualizowałem również kod tak, aby zawierał wszystko: – Olumide

2

Myślę, że musisz utrzymywać obiekt anim jako zmienną poziomu klasy, onLongClick() i onClick() zostaje wywołany w nakładających się modach w wielu przypadkach. Ponieważ masz różne obiekty animacji, uzyskujesz dostęp do tego samego obiektu z dwóch obiektów animacji.

Zachowaj animację na zewnątrz i opublikuj swoją obserwację.

i spróbuj usunąć metody onLongClick() lub onClick(). w miarę możliwości dodaj te dwie metody, aby zrozumieć kolejność wywołań.

Będę czekał na twoje spostrzeżenia.

1

Trzeba użyć ViewPropertyAnimator do tej pracy. Animacja w rzeczywistości nie przesuwa samego widoku, tylko bitmapową reprezentację widoku, zgodnie z opisem here.

3

Aktualizacja: to teraz załóżmy, który zostanie ustalony na poparcie lib 24.2.0 po bug mam otworzony https://code.google.com/p/android/issues/detail?id=215043

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

dla tych z nas, które nie szczęście wystarczy zastąpić ich animację z ViewPropertyAnimation jak ja:

Ten błąd zdarza się z powodu błędu w realizacji nośnej FloatingActionButton, określonego w klasie FloatingActionButtonEclairMr1, gdzie ustawienie animacji dla wszystkich przeglądać stany, więc po kliknięciu widoku jest uruchamiana animacja FloatingActionButtonEclairMr1.ElevateToTranslationZAnimation, więc animacja jest usuwana z widoku.

Najprostsze rozwiązanie, które mam znaleźć dopiero zaczyna swoją animację z pewnym opóźnieniem, NIE z startOffset (bo nadal będzie przesłanianie przez animacji tłoczenia), ale z wywołaniem animację z opóźnieniem (jestem . przy użyciu 100, ale również sprawdzić z 60 i to działało 20 nie wystarczy):

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