TL; DR: Szukam kompletnej, działającej próbki tego, co będę nazywać scenariuszem „trzyczęściowej animacji Gmaila”. W szczególności chcemy zacząć od dwóch fragmentów, takich jak ten:
Po jakimś zdarzeniu interfejsu użytkownika (np. Dotknięciu czegoś we fragmencie B) chcemy:
- Fragment A, aby zsunąć się z ekranu w lewo
- Fragment B przesuwa się do lewej krawędzi ekranu i zmniejsza się, aby zająć miejsce zwolnione przez Fragment A
- Fragment C, aby wślizgnąć się z prawej strony ekranu i zająć miejsce zwolnione przez Fragment B.
A po naciśnięciu przycisku WSTECZ chcemy, aby ten zestaw operacji został odwrócony.
Teraz widziałem wiele częściowych implementacji; Poniżej omówię cztery z nich. Poza tym, że są niekompletne, wszystkie mają swoje problemy.
@Reto Meier przesłał tę popularną odpowiedź na to samo podstawowe pytanie, wskazując, że użyjesz setCustomAnimations()
pliku FragmentTransaction
. W przypadku scenariusza z dwoma fragmentami (np. Początkowo widzisz tylko Fragment A i chcesz go zastąpić nowym Fragmentem B przy użyciu animowanych efektów), zgadzam się całkowicie. Jednak:
- Ponieważ możesz określić tylko jedną animację „wchodzącą” i jedną „wychodzącą”, nie widzę, jak poradzisz sobie ze wszystkimi różnymi animacjami wymaganymi w scenariuszu z trzema fragmentami
- W
<objectAnimator>
swoim przykładowym kodzie używa ustalonych pozycji w pikselach, co wydaje się niepraktyczne biorąc pod uwagę różne rozmiary ekranu, alesetCustomAnimations()
wymaga zasobów animacji, wykluczając możliwość zdefiniowania tych rzeczy w Javie - Nie wiem, jak animatory obiektów dla skali wiążą się z takimi rzeczami, jak
android:layout_weight
wLinearLayout
przypadku przydzielania miejsca na podstawie procentowej - Jestem w rozterce, w jaki Fragment C odbywa się na początku (
GONE
?android:layout_weight
O0
? Pre-animowane w skali od 0? Coś innego?)
@Roman Nurik zwraca uwagę, że możesz animować każdą właściwość , w tym tę, którą sam zdefiniujesz. Może to pomóc rozwiązać problem stałych pozycji kosztem wynalezienia własnej podklasy menedżera niestandardowego układu. To pomaga niektórym, ale nadal jestem zdumiony resztą rozwiązania Reto.
Autor tego wpisu w pastebin pokazuje jakiś kuszący pseudokod, mówiąc w zasadzie, że wszystkie trzy fragmenty znajdowałyby się początkowo w kontenerze, z Fragmentem C ukrytym na początku w wyniku hide()
operacji transakcyjnej. Następnie show()
C i hide()
A, gdy wystąpi zdarzenie UI. Jednak nie rozumiem, jak to radzi sobie z faktem, że B zmienia rozmiar. Polega to również na tym, że najwyraźniej można dodać wiele fragmentów do tego samego kontenera i nie jestem pewien, czy jest to niezawodne zachowanie w dłuższej perspektywie (nie wspominając o tym, że powinno się zepsuć findFragmentById()
, chociaż mogę z tym żyć).
Autor tego posta na blogu wskazuje, że Gmail setCustomAnimations()
w ogóle nie używa , ale zamiast tego bezpośrednio używa animatorów obiektów („po prostu zmień lewy margines widoku głównego + zmień szerokość prawego widoku”). Jednak nadal jest to dwuczęściowe rozwiązanie AFAICT, a implementacja pokazała po raz kolejny sztywne wymiary w pikselach.
Będę dalej się tym zajmował, więc może kiedyś sam na to odpowiem, ale naprawdę mam nadzieję, że ktoś opracował rozwiązanie z trzema fragmentami dla tego scenariusza animacji i może opublikować kod (lub link do niego). Animacje w Androidzie sprawiają, że chcę wyrywać sobie włosy, a ci z Was, którzy mnie widzieli, wiedzą, że jest to w dużej mierze bezowocne przedsięwzięcie.