2

Zuerst dachte ich, dass meine Animationen überhaupt nicht funktionierten, weil die neue Fragment ViewGroup nur auf dem Bildschirm in einem Frame erscheinen würde. Dann verlangsamte ich die Animation, so dass es 3 Sekunden (3000 Millisekunden) dauerte und entdeckte, dass es gerade in so großen Brocken passiert, dass alles in einem Frame passiert ist. Als ich es auf 3 Sekunden erhöhte, kam es auf 4 Bilder pro Sekunde, was ziemlich schlecht ist. Ich laufe mit einem Genymotion Emulator. Der Emulator scheint im Allgemeinen sehr schnell zu sein, wenn ich zum Beispiel durch die Einstellungen-App klicke.Android ObjektAnimator Animationen sind wirklich langsam

Ich fange gerade an, Entwicklung auf dieser Anwendung zu beginnen, also tut es nichts. Es ist bisher meistens nur eine Shell und ich versuche ein neues Fragment auf dem Bildschirm zu animieren.

Der neue Viewgroup ist eine benutzerdefinierte Klasse SlideableLayout genannt, die diese Eigenschaft bietet:

public float getXFraction() { 
    final int width = getWidth(); 
    if (width != 0) { 
     return getX()/getWidth(); 
    } else { 
     return getX(); 
    } 
} 

public void setXFraction(float xFraction) { 
    Log.d("SL", "setting xFraction="+xFraction); 
    final int width = getWidth(); 
    if (width > 0) { 
     setX(xFraction * width); 
    } else { 
     setX(-10000); 
    } 
} 

Dann füge ich das Fragment in etwa so:

getFragmentManager() 
    .beginTransaction() 
    .setCustomAnimations(R.animator.slide_in_from_right, R.animator.slide_out_to_the_left, 
      R.animator.slide_in_from_the_left, R.animator.slide_out_to_the_right) 
    .add(R.id.navrootlayout, fragment) 
    .addToBackStack(null) 
    .commit(); 

Die R.animator.slide_in_from_right Animation sieht wie folgt aus:

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android"> 
    <objectAnimator 
     android:interpolator="@interpolator/decelerate_cubic" 
     android:valueFrom="1" 
     android:valueTo="0" 
     android:valueType="floatType" 
     android:propertyName="xFraction" 
     android:duration="@integer/navigation_animation_duration"/> 
</set> 

Also sollte das System dieanimierenEigenschaft von 1.0 zu 0.0 und jeder Rahmen sollte sehr schnell berechnet werden, da alles, was es tut, die width bekommt und mit dem Bruch multipliziert.

Ich bin mir nicht sicher, warum es mit einer so niedrigen Bildrate läuft. Ich habe es auf einem physischen Gerät versucht und es war in Ordnung.

EDIT:

Gibt es einige Arten von Konfigurationsoptionen, die ich auf meinem Genymotion Emulator, um festlegen müssen die Animationen in einem normalen Bildrate gehen zu machen?

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

+0

Wie ist die Dauer eingestellt? – JoxTraex

+0

3000 Millisekunden (d. H. 3 Sekunden) –

+0

Wird eine benutzerdefinierte Test-App verwendet, um den Code aus der Animationsgleichung zu entfernen? Sie möchten es isolieren, um festzustellen, ob es ein Codeproblem ist oder ob es ein Animationsproblem ist. Durch Isolieren des Animationscodes in einem einfachen Test-App-Szenario können Sie diese Bedingungen isolieren. – JoxTraex

Antwort

0

Offenbar wird dies durch xFraction und yFraction verursacht wird, die durch beide Fragmente root Ansichten implementiert werden müssen, : https://stackoverflow.com/a/25701362/2964379

Ehrlich gesagt, das ist nur ein episches Versagen. Erwartet Google, dass Nutzer jede einzelne Ansicht erweitern, nur um diese beiden Methoden hinzuzufügen?

Eine einfache, aber schreckliche Lösung besteht darin, die Eigenschaft auf x oder y zu setzen und die Werte auf eine große Zahl gleich oder größer als der Bildschirm einzustellen, dann funktioniert es schnell, aber abhängig vom Wert können große Lücken in der Animation.

Die beste Lösung (von https://stackoverflow.com/a/20480676/2964379) ist, Ihre Animatoren auf x oder y einzustellen, aber entfernen Sie valueFrom und valueTo vollständig. Überschreibe dann alle Fragmente 'onCreateAnimator (in einer benutzerdefinierten Fragment-Basisklasse), benutze AnimatorInflater.loadAnimator(activity, nextAnim), um den Animator zu erhalten und rufe setFloatValues auf seinem Kind an.Zum Beispiel können Sie nextAnim == R.animator.slide_in_from_right überprüfen und setFloatValues(screenWidth, 0) anrufen. Funktioniert super!