2016-08-12 13 views
6

Co próbuję wykonaćJak animować elementy RecyclerView po zainicjowaniu adaptera (w kolejności)?

chcę, aby elementy liniowo RecyclerView pionowej wyświetlane w kolejności. Chcę, aby pierwszy element pojawił się, następnie drugi, trzeci i tak dalej. Oto przykład typu animacji, którą próbuję wykonać.

animation example


Co Próbowałem

Próbowałem metod przewidzianych w tej kwestii: How to animate RecyclerView items when they appear

Jest to jednak nie do końca to, co usiłuję ukończyć. Powoduje to, że wszystkie elementy w RecyclerView pojawiają się jednocześnie, a nie pojedynczo.


Mój kod

public class ParentCommentsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 

    private int lastPosition = -1; 

    //constructor and other code not shown... 

    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { 
     switch (viewHolder.getItemViewType()) { 
      case OP: 
       OPViewHolder ovh = (OPViewHolder) viewHolder; 
       configureOPViewHolder(ovh, position); 
       setAnimation(ovh.getContainer(), position); 
       break; 
      case COMMENT: 
       CommentViewHolder cvh = (CommentViewHolder) viewHolder; 
       configureCommentViewHolder(cvh, position); 
       setAnimation(cvh.getContainer(), position); 
       break; 
      default: 
       RecyclerViewSimpleTextViewHolder vh = (RecyclerViewSimpleTextViewHolder) viewHolder; 
       configureDefaultViewHolder(vh, position); 
       break; 
     } 

    } 

    @Override 
    public void onViewDetachedFromWindow(final RecyclerView.ViewHolder viewHolder) 
    { 

     switch (viewHolder.getItemViewType()) { 
      case OP: 
       ((OPViewHolder)viewHolder).clearAnimation(); 
       break; 
      case COMMENT: 
       ((CommentViewHolder)viewHolder).clearAnimation(); 
       break; 
      default: 
       break; 
     } 
    } 

    private void configureDefaultViewHolder(RecyclerViewSimpleTextViewHolder vh, int position) { 
     //code... 
    } 

    private void configureOPViewHolder(OPViewHolder vh1, int position) { 
     //code... 
    } 

    private void configureCommentViewHolder(CommentViewHolder vh2, int position) { 
     //code... 
    } 

    private void setAnimation(View viewToAnimate, int position) 
    { 
     // If the bound view wasn't previously displayed on screen, it's animated 
     if (position > lastPosition) 
     { 
      Animation animation = AnimationUtils.loadAnimation(context, R.anim.fade_in); 
      viewToAnimate.startAnimation(animation); 
      lastPosition = position; 
     } 
    } 

} 
+0

Czy brałeś pod uwagę projekt OSS, taki jak https://github.com/wasabeef/recyclerview-animators? –

+0

@SebastianRoth Przebiegłem przez ten projekt podczas badania. Ten projekt wydaje się mieć wiele animacji, ale mam już własną animację, której chcę użyć. Mój problem polega na tym, że chcę, aby elementy do recyclerview były animowane w kolejności, gdy działanie jest otwierane początkowo. Kiedy więc czynność zostanie otwarta, chcę, aby element pierwszy był animowany, a następnie element 2, a następnie element 3 i tak dalej. –

Odpowiedz

9

Po wywołaniu setAdapter można uruchomić następujące:

recyclerView.getViewTreeObserver().addOnPreDrawListener(
     new ViewTreeObserver.OnPreDrawListener() { 

      @Override 
      public boolean onPreDraw() { 
       recyclerView.getViewTreeObserver().removeOnPreDrawListener(this); 

       for (int i = 0; i < recyclerView.getChildCount(); i++) { 
        View v = recyclerView.getChildAt(i); 
        v.setAlpha(0.0f); 
        v.animate().alpha(1.0f) 
          .setDuration(300) 
          .setStartDelay(i * 50) 
          .start(); 
       } 

       return true; 
      } 
     }); 

Przykład pokazuje prostą animację alfa, ale można uruchomić, co chcesz w pętli i dostosuj interpolator, czas trwania i opóźnienie startu.

+0

To zadziałało, po prostu zastąpiłem animację własną. Wygląda na to, że kluczem jest dodanie opcji setStartDelay i zmiana opóźnienia w stosunku do pozycji przedmiotu. Dziękuję bardzo, Niko. –

+0

Czy istnieje sposób na usunięcie OnPreDrawListener? Powiedzmy, że chcę później użyć innej animacji, jak to zrobić? Próbowałem dodać inną metodę, która była taka sama jak tutaj, ale z inną animacją, ale wydaje się, że po prostu dodaje tę animację do aktualnej animacji. –

+0

To jest jednorazowy wyzwalacz po wywołaniu setAdapter, metoda removeOnPreDrawListener jest wywoływana w metodzie onPreDraw. Jeśli chcesz później inną animację, wywołujesz setAdapter lub dodajesz/usuwasz elementy za pomocą istniejącego adaptera? – Niko

3

Postanowiłem zastosować inne podejście niż sugerował wcześniej Niko. Jego metoda działa świetnie i jest bardzo łatwa, ale powodowała pewne błędne animacje podczas dodawania i usuwania elementów (as can be seen here).

Postanowiłem więc wypróbować inne podejście i użyć kontrolera animacji układu. Oto kod, którego użyłem do osiągnięcia tego samego wyniku.

public void initialRVAnimation() { 

    AnimationSet set = new AnimationSet(true); 

    // Fade in animation 
    Animation fadeIn = new AlphaAnimation(0.0f, 1.0f); 
    fadeIn.setDuration(400); 
    fadeIn.setFillAfter(true); 
    set.addAnimation(fadeIn); 

    // Slide up animation from bottom of screen 
    Animation slideUp = new TranslateAnimation(0, 0, Utils.getScreenHeight(this), 0); 
    slideUp.setInterpolator(new DecelerateInterpolator(4.f)); 
    slideUp.setDuration(400); 
    set.addAnimation(slideUp); 

    // Set up the animation controller    (second parameter is the delay) 
    LayoutAnimationController controller = new LayoutAnimationController(set, 0.2f); 
    rv.setLayoutAnimation(controller); 

    // Set the adapter 
    adapter = new ItemAdapter(data, this); 
    recyclerView.setAdapter(adapter); 
} 
+0

Wdrażam to samo, ale kiedy zastosuję twoją odpowiedź lub zaakceptowaną odpowiedź, to nie działa ona dla mnie. dla początkowej pozycji nie widać animacji. wszystkie pojawiają się w tym samym czasie. Czy możesz mi coś zasugerować? – djk

+0

Część kontrolująca opóźnienie jest drugim parametrem LayoutAnimationController. Upewnij się, że ustawiasz animację układu, wykonując 'recyclerView.setLayoutAnimation (kontroler)' –

Powiązane problemy