1

Ich habe die Methode in this question implementiert und die Animation auf Bildlauf sieht vollkommen in Ordnung. Die anfängliche Listenfüllungsanimation zeigt jedoch an, dass alle Objekte gleichzeitig auf dem Bildschirm angezeigt werden, und es sieht nur wie eine Verzögerung aus.RecyclerView Elemente animieren auf Liste füllen, aber die ersten Elemente alle gleichzeitig animieren und sieht nur aus wie eine Verzögerung

Während des Debuggens kann ich sehen, dass die Animationsmethode 7-mal aufgerufen wird, aber ich denke, es ist so schnell, dass alle versuchen, im Grunde zur gleichen Zeit zu laufen. Irgendwelche Ideen, was ich tun kann? Ich habe versucht, die Animation zu verzögern, aber ich blieb stecken, wie das geht. Ich habe diese Frage gestellt here. Vielen Dank für die Hilfe!

Edit: Ich kann den gleichen Code schreiben, die ich auf die andere Frage stellen:

public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position) 
    { 
     //Normal OnBindViewHolder stuff 
     SetAnimation(vh.ItemView, position); 
    } 

Und dann die SetAnimation Methode:

private void SetAnimation(View viewToAnimate, int position) 
    { 
     if (position > lastPosition) 
     { 
      var animation = AnimationUtils.LoadAnimation(_context, Resource.Animation.up_from_bottom); 
      //animation.SetAnimationListener(new CheckpointAnimationListener()); 
      viewToAnimate.StartAnimation(animation); 
      lastPosition = position; 
     } 
    } 

Was ich wirklich hier wollen, ist für die Animation fertigstellen bevor die lastPosition = positionslinie aufgerufen wird.

Und der leere AnimationsListener, da ich mir wirklich nicht sicher bin, wie ich mit dem Warten umgehen soll.

private class CheckpointAnimationListener : Java.Lang.Object, Animation.IAnimationListener 
    { 
     public void OnAnimationEnd(Animation animation) 
     { 

     } 

     public void OnAnimationRepeat(Animation animation) 
     { 

     } 

     public void OnAnimationStart(Animation animation) 
     { 

     } 
    } 

Antwort

0

Die Antwort von Gil schickte mich in die richtige Richtung, aber da ich mit Xamarin.Android arbeite, musste ich ein paar Dinge anders machen. Ich habe stattdessen seine Idee für StartOffset verwendet, da C# keine anonymen Klassen verwendet (wodurch Runnables wesentlich schwieriger werden). Hier ist mein endgültiger Animationscode (nachdem ich mit den Verzögerungen herumgespielt habe).

private void SetAnimation(View viewToAnimate, int position) 
    { 
     var animation = AnimationUtils.LoadAnimation(_context, Resource.Animation.up_from_bottom); 

     _currentTime = JavaSystem.CurrentTimeMillis(); 

     long difference = _currentTime - _timeAtFirstCall; 

     //this will cause the first items to populate the view to animate in order instead of at the same time. 
     //_delay is increased each time so each item will start 75ms after the one before it. difference is 
     //there to make sure later items in the list dont get this delay and animate as they appear. 
     if (_nextAnimationStartTime > _currentTime && difference < 150) 
     { 
      if (position > lastPosition) 
      { 
       animation.StartOffset = _delay; 
       viewToAnimate.StartAnimation(animation); 
       lastPosition = position; 
       _delay += 75; 
      } 

     } 
     else 
     { 
      if (position > lastPosition) 
      { 
       animation.StartOffset = 75; 
       viewToAnimate.StartAnimation(animation); 
       lastPosition = position; 
      } 
     } 

     _nextAnimationStartTime = _currentTime + 400; 

    } 

Und dann hatte ich diese Variablen an der Spitze der Klasse definiert und initialisiert:

private int lastPosition = -1; 
    private long _nextAnimationStartTime = 0; 
    private long _currentTime = 0; 
    private long _timeAtFirstCall = JavaSystem.CurrentTimeMillis(); 
    private long _delay = 150; 

Diese Methode am Ende des OnBindViewHolder genannt wird. Jetzt, wenn OnBindViewHolder zum ersten Mal aufgerufen wird, wird die else-Anweisung durchlaufen. Ich musste auch hier eine erste Verzögerung einstellen, weil die Animation sonst auf dem Bildschirm halbwegs anfing und einfach schlecht aussah. Diese Verzögerung sorgt auch dafür, dass die Objekte bei einem schnellen Bildlauf nacheinander animiert werden.

Das einzige Problem, das ich immer noch habe, ist, wenn der Benutzer sofort scrollt, wenn er die Ansicht lädt. Die ersten Elemente behalten ihre Verzögerung bei, aber das erste Element, das beim Scrollen auf animiert wird, startet möglicherweise seine Animation, bevor die ersten Elemente beendet werden. Ich bin mir nicht sicher, wie ich dieses Problem umgehen kann ...

0

Ich musste etwas ähnliches tun. Grundsätzlich war der Ansatz, den ich wann immer ich begann eine Animation, ich informiert auch, wenn die minimale Startzeit würde, basierend auf dem letzten Mal die Animation wurde initiiert.

Da Sie keinen Code schreiben habe, werde ich eine Grundzüge schreiben, was ich tat:

// member to know when the minimum start time of the next animation will be. 
private long mNextAnimationStartTime; 

... 

public void onBindViewHolder(...) { 
    // perform binding logic 

    // sample the current time. 
    long currentTime = System.currentTimeMillisec(); 

    // if the next animation time is greater than now... 
    if (mNextAnimationStartTime > currentTime) { 

     // calculate how much time to wait before showing the next animation. 
     int delay = mNextAnimationStartTime - currentTime; 

     // In this example, I use postDelayed to postpone the animation, 
     // but you could also use start offset of the animation itself. 
     postDelayed(new Runnable() { 
      @Override 
      public void run() { 

       // start the animation after a delay. 
       startAnimation(viewToAnimate); 
      } 
     }, delay); 
    } else { 

     // if the next animation time is in the past, just start the animation. 
     startAnimation(viewToAnimate); 
    } 

    // schedule the next animation start time to now + 100 ms (play with this 100 to fit your needs) 
    mNextAnimationStartTime = currentTime + 100; 
} 

Hoffnung war klar, und Sie beginnen können.

+0

Ich kopierte meinen Code von meiner vorherigen Frage und steckte ihn in diesen ein. Aber dein Code gibt mir eine gute Idee, wohin ich gehen soll :) Ich arbeite in Xamarin.Android, also muss ich ein paar Dinge anders machen, aber deine Idee ist gut. –

Verwandte Themen