2012-08-13 11 views
22

Mam LinearLayout, którego używam jako kontenera dla niektórych przycisków i widoków tekstowych, które chciałbym animować wysokością, aby dać wrażenie zsuwania się układu, gdy użytkownik naciśnie ". pokaż ".Animacja wysokości kontenera LinearLayout z ValueAnimatorem

Ustawiłem LinearLayout na layout_height = "0dp" i visibility = "gone" w moim xml. Następnie chciałbym ustawić, aby był widoczny i jakakolwiek wysokość jest potrzebna do zawinięcia zawartości. W tej chwili mam problemy z animacją w ogóle, nie podważaj wysokości zawartości wrapów.

Oto moja metoda animowania:

private void toggle(final LinearLayout v) { 
    v.setVisibility(View.VISIBLE); 
    ValueAnimator va = ValueAnimator.ofInt(0, 300); 
    va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
     public void onAnimationUpdate(ValueAnimator animation) { 
      Integer value = (Integer) animation.getAnimatedValue(); 
      v.getLayoutParams().height = value.intValue(); 
      v.invalidate(); 

     } 
    }); 

    va.start(); 
} 

Być może jest problem jak ja ustawiania wysokości LinearLayout? Czy nie rozumiem funkcji ValueAnimatora? Rozejrzałem się po postach na blogu Cheta Haase'a, ale nie zawierają one żadnych konkretnych przykładów animacji wysokości. Nie byłem też w stanie znaleźć i dobrych przykładów, jak pracować z animacjami wysokości za pomocą API z wersji 3.0+. Chciałbym pomóc w tym, dzięki!

+0

Dlaczego po prostu nie użyć animacji układu? –

+0

Szczerze mówiąc nie mam pojęcia, jak z niego korzystać i doszedłem do wniosku, że skoro jestem nastawiony tylko na nowsze wersje interfejsu API, łatwiej byłoby używać nowszych klas ... Będę się dalej zastanawiać, jak to zrobić z LayoutAnimation, jeśli masz pomysł, jak to zrobić, możesz go opublikować jako lepsze rozwiązanie :) – span

+0

Czy istnieje jakiś powód do unieważnienia? – portfoliobuilder

Odpowiedz

57

Patrząc na ten wpis na blogu: http://tech.chitgoks.com/2011/10/29/android-animation-to-expand-collapse-view-its-children/ Stwierdziłem, że nie powinienem używać view.invalidate(), aby przerysować układ. Powinienem użyć view.requestLayout().

Zatem kod staje się coś takiego:

ValueAnimator va = ValueAnimator.ofInt(0, height); 
    va.setDuration(700); 
    va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
     public void onAnimationUpdate(ValueAnimator animation) { 
      Integer value = (Integer) animation.getAnimatedValue(); 
      v.getLayoutParams().height = value.intValue(); 
      v.requestLayout(); 
     } 
    }); 

Chciałem tylko dodać notatkę o tym, jak uzyskać wysokość LinearLayout także, aby animacja dynamiczna. Aby uzyskać wysokość, wszystkie widoki muszą zostać narysowane jako pierwsze. Therfor musimy posłuchać zdarzenia, które mówi nam, że rysunek się skończył. Można to zrobić za pomocą metody onResume() w ten sposób (zauważ, że w moim xml zadeklarowałem kontener do wrap_content na wysokość i jest on również widoczny, ponieważ chcę go ukryć od samego początku, robię to po jego pomiarze):

@Override 
    public void onResume() { 
     super.onResume(); 
     final ViewTreeObserver vto = filterContainer.getViewTreeObserver(); 
     vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
      @Override 
      public void onGlobalLayout() { 
       height = filterContainer.getHeight(); 
       filterContainer.setVisibility(View.GONE); 
       filterContainer.getLayoutParams().height = 0; 
       filterContainer.requestLayout(); 
       ViewTreeObserver obs = filterContainer.getViewTreeObserver(); 
       obs.removeGlobalOnLayoutListener(this); 
      } 
     }); 
    } 
+3

Pomogło mi to zrozumieć, jak korzystać z getAnimatedValue. Dzięki – speedynomads

+0

Lepsze działanie animatora wartości polega na przyjmowaniu wartości pośrednich między punktem początkowym i końcowym dla określonego czasu trwania, a my możemy aktualizować wysokość naszego układu przez tę wartość pośrednią, aż osiągniemy wysokość docelową. Animacja jest również bardzo płynna. Dzięki. –

+0

Dziękuję bardzo! Druga część odpowiedzi bardzo mi pomaga! – Victor