Powiedzmy, że mam pionowy układ liniowy z:
[v1]
[v2]
Domyślnie v1 ma visibily = GONE. Chciałbym pokazać v1 z animacją rozwijania i jednocześnie nacisnąć v2.
Próbowałem czegoś takiego:
Animation a = new Animation()
{
int initialHeight;
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final int newHeight = (int)(initialHeight * interpolatedTime);
v.getLayoutParams().height = newHeight;
v.requestLayout();
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
initialHeight = height;
}
@Override
public boolean willChangeBounds() {
return true;
}
};
Ale dzięki temu rozwiązaniu mam mrugnięcie, gdy rozpoczyna się animacja. Myślę, że jest to spowodowane wyświetlaniem pełnego rozmiaru v1 przed zastosowaniem animacji.
W javascript jest to jedna linia jQuery! Jakiś prosty sposób to zrobić na Androidzie?
a.setDuration(((int)(initialHeight / v.getContext().getResources().getDisplayMetrics().density)) * 4)
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
iv.getLayoutParams().height = interpolatedTime == 1 ? targetHeight : (int)(targetHeight * interpolatedTime);
To działało dla mnie!Próbowałem zrobić coś, co według mnie było bardzo podobną animacją, i znalazłem eleganckie rozwiązanie. Ten kod zakłada, że zawsze zaczynasz od 0-> h lub h-> 0 (h to maksymalna wysokość). Trzy parametry konstruktora to view = widok do animacji (w moim przypadku webview), targetHeight = maksymalna wysokość widoku i down = wartość logiczna określająca kierunek (true = rozwijanie, false = zwijanie).
źródło
Natknąłem się dzisiaj na ten sam problem i wydaje mi się, że prawdziwym rozwiązaniem tego pytania jest to
Musisz ustawić tę właściwość dla wszystkich najwyższych układów, które biorą udział w zmianie. Jeśli teraz ustawisz widoczność jednego układu na BRAK, drugi zajmie miejsce, gdy zniknie jeden z nich. Będzie domyślna animacja, która jest pewnego rodzaju „zanikaniem”, ale myślę, że możesz to zmienić - ale ostatnią, której na razie nie testowałem.
źródło
Wziąłem rozwiązanie @LenaYan, które nie działało dla mnie poprawnie ( ponieważ przekształcało widok do widoku o wysokości 0 przed zwinięciem i / lub rozwinięciem ) i wprowadziłem pewne zmiany.
Teraz działa świetnie , biorąc poprzednią wysokość widoku i zacznij powiększać z tym rozmiarem. Składanie jest takie samo.
Możesz po prostu skopiować i wkleić poniższy kod:
Stosowanie:
Wystarczająco łatwe!
Dzięki LenaYan za kod początkowy!
źródło
Alternatywą jest użycie animacji skali z następującymi czynnikami skalowania do rozwijania:
i do zwijania:
źródło
@Tom Esterez za odpowiedź , ale zaktualizowany do korzystania view.measure () właściwie za Android getMeasuredHeight zwraca błędne wartości!
źródło
Ok, właśnie znalazłem BARDZO brzydkie rozwiązanie:
Zapraszam do zaproponowania lepszego rozwiązania!
źródło
View.onMeause(widthMeasureSpec, heightMeasureSpec)
wywołaniu jest mały błąd , więc specyfikacje szerokości i wysokości powinny zostać zamienione.źródło
Jeśli nie chcesz rozwinąć ani zwinąć do końca - oto prosta wysokośćAnimacja -
Stosowanie:
źródło
Dostosowałem obecnie akceptowaną odpowiedź Toma Estereza , który działał, ale miał niespokojną i niezbyt płynną animację. Moje rozwiązanie w zasadzie zastępuje literę „
Animation
a”ValueAnimator
, którą można wyposażyćInterpolator
w dowolne wybrane ustawienie, aby osiągnąć różne efekty, takie jak przeregulowanie, odbicie, przyspieszenie itp.To rozwiązanie świetnie sprawdza się w widokach o dynamicznej wysokości (tj. Przy użyciu
WRAP_CONTENT
), ponieważ najpierw mierzy rzeczywistą wymaganą wysokość, a następnie animuje do tej wysokości.Następnie wystarczy zadzwonić
expand( myView );
lubcollapse( myView );
.źródło
v.measure()
i teraz działa idealnie. Dzięki!Korzystając z funkcji rozszerzających Kotlin jest to przetestowana i najkrótsza odpowiedź
Wystarczy wywołać funkcję animateVisibility (rozwinąć / zwinąć) w dowolnym widoku.
źródło
Dodając do doskonałej odpowiedzi Toma Estereza i doskonałej aktualizacji Erika B , pomyślałem, że opublikuję własne ujęcie, łącząc metody rozwijania i kontraktowania w jedną. W ten sposób możesz na przykład wykonać taką akcję ...
... który wywołuje poniższą metodę i pozwala jej dowiedzieć się, co zrobić po każdej operacji onClick () ...
źródło
Chciałbym dodać coś do bardzo pomocnej odpowiedzi powyżej . Jeśli nie znasz wysokości, na której się skończysz, ponieważ Twoje widoki .getHeight () zwraca 0, możesz wykonać następujące czynności, aby uzyskać wysokość:
Tam, gdzie DUMMY_HIGH_DIMENSIONS jest szerokością / wysokością (w pikselach), twój widok jest ograniczony do ... posiadanie tej ogromnej liczby jest rozsądne, gdy widok jest zamknięty w ScrollView.
źródło
Jest to fragment, którego użyłem do zmiany szerokości widoku (LinearLayout) z animacją.
Kod ma się rozszerzać lub zmniejszać zgodnie z wielkością docelową. Jeśli chcesz szerokość fill_parent, musisz podać rodzic .getMeasuredWidth jako szerokość docelową, ustawiając flagę na true.
Mam nadzieję, że to pomoże niektórym z was.
}
źródło
resizeAnim.start()
. Próbowałem również zi bezsetFillAfter(true)
.startAnimation(resizeAnim)
na widok.Aby uzyskać płynną animację, użyj modułu obsługi z metodą uruchamiania ..... I ciesz się animacją Rozwiń / Zwiń
I zadzwoń, używając tego kodu:
Inne rozwiązanie to:
źródło
połączone rozwiązania @Tom Esterez i @Geraldo Neto
źródło
Tak, zgodziłem się z powyższymi komentarzami. I rzeczywiście wydaje się, że właściwą (a przynajmniej najłatwiejszą?) Rzeczą jest określenie (w XML) początkowej wysokości układu „0px” - a następnie można podać kolejny argument dla „toHeight” ( tj. „wysokość końcowa”) do konstruktora niestandardowej podklasy Animacji, np. w powyższym przykładzie wyglądałoby to tak:
W każdym razie, mam nadzieję, że to pomaga! :)
źródło
Oto moje rozwiązanie. Myślę, że to jest prostsze. To tylko rozszerza widok, ale można go łatwo rozszerzyć.
źródło
Myślę, że najprostszym rozwiązaniem jest zestaw
android:animateLayoutChanges="true"
doLinearLayout
i po prostu pokazać / ukryć widzenia przez seting swoją widoczność. Działa jak urok, ale nie masz kontroli nad czasem trwania animacjiźródło
Jesteś na dobrej drodze. Upewnij się, że masz v1 ustawiony na zerową wysokość układu tuż przed rozpoczęciem animacji. Chcesz zainicjować konfigurację, aby wyglądała jak pierwsza klatka animacji przed rozpoczęciem animacji.
źródło
To było moje rozwiązanie, mój
ImageView
rośnie od100%
celu200%
i wrócić do swojego pierwotnego rozmiaru, przy użyciu dwóch plików animacji wewnątrzres/anim/
folderuanim_grow.xml
anim_shrink.xml
Wyślij
ImageView
do mojej metodysetAnimationGrowShrink()
setAnimationGrowShrink()
metoda:źródło
To jest właściwe działające rozwiązanie, przetestowałem to:
Exapnd:
Zawalić się:
Animator wartości:
Widok v to widok do animacji, PARENT_VIEW to widok kontenera zawierający widok.
źródło
To jest naprawdę proste dzięki droidQuery . Na początek rozważ ten układ:
Możemy animować wysokość do pożądanej wartości - powiedzmy
100dp
- używając następującego kodu:Następnie użyj
droidQuery
do animacji. Najprostszy sposób to:Aby animacja była bardziej atrakcyjna, rozważ dodanie łagodzenia:
Możesz także zmienić czas trwania przy
AnimationOptions
użyciu tejduration()
metody lub obsłużyć to, co się stanie po zakończeniu animacji. Dla złożonego przykładu spróbuj:źródło
Najlepsze rozwiązanie dla widoków rozwijania / zwijania:
źródło
onCheckedChanged
.Możesz użyć ViewPropertyAnimator z lekkim zwrotem akcji. Aby zwinąć, przeskaluj widok do wysokości 1 piksela, a następnie ukryj go. Aby rozwinąć, pokaż go, a następnie rozwiń na wysokość.
Oś określa widok, z którego miejsca ma być skalowana, domyślnie jest na środku. Czas trwania jest opcjonalny (domyślnie = 1000). Możesz także ustawić interpolator na użycie, np
.setInterpolator(new AccelerateDecelerateInterpolator())
źródło
Stworzyłem wersję, w której nie musisz określać wysokości układu, dlatego jest o wiele łatwiejszy i czystszy w użyciu. Rozwiązaniem jest uzyskanie wysokości w pierwszej klatce animacji (jest ona dostępna w tym momencie, przynajmniej podczas moich testów). W ten sposób możesz zapewnić widok z dowolną wysokością i dolnym marginesem.
Jest też jeden mały hack w konstruktorze - dolny margines jest ustawiony na -10000, więc widok pozostaje ukryty przed transformacją (zapobiega migotaniu).
źródło
Użyj ValueAnimator:
źródło
mainView.getLayoutParams().height = height
.źródło
Klasę można wywołać w następujący sposób
źródło
Na podstawie rozwiązań @Tom Esterez i @Seth Nelson (pierwsza 2) uprościłem je. Oprócz oryginalnych rozwiązań nie zależy to od opcji programisty (ustawienia animacji).
źródło