#3 Animacja opadania, ruch jest ważny!

Wraz z pojawieniem się Androida Lollipop w systemie Android pojawiło się sporo ciekawych animacji. Po wcześniejszych wersjach to była prawdziwa rewolucja, ludzie naprawdę potrzebowali ładnych rzeczy (swego czasu jeszcze przed Androidem 5.0 w sklepie Play przez jakiś czas bardzo popularny był kalkulator. Nie dlatego, że był super kalkulatorem, był po prostu kalkulatorem. Ale był bardzo ładny, naprawdę dopracowany pod względem designu i to wystarczyło, żeby coś tak oczywistego jak kalkulator, stało się jedną z najpopularniejszych aplikacji. Nie pamiętam jak się nazywał, to była moja własna obserwacja, ale wnioskuję, że ludzie pragnęli ślicznych aplikacji). Razem z tymi animacjami pojawiło się sporo wytycznych i przykładów jak powinny wyglądać i zachowywać się aplikacje w stylu Material Design, np tutaj. O albo taki widoczek:
Wygląda naprawdę dobrze, spróbujmy więc może zrobić chociaż namiastkę tego co tam widać. 😉
Problemem z którym musiałem się dzisiaj zmierzyć była animacja. Celem było osiągnięcie jak najbardziej „naturalnego efektu” podczas opadania klocków na stos. Chcemy, aby użytkownik odniósł wrażenie, że oto prawdziwy klocek upada, żeby był w stanie fizycznie „w życiu” sobie taką sytuację wyobrazić. Cały czas mamy w pamięci, że użytkownikami są dzieciaki, które nigdy nie miały kontaktu z technologią, nie możemy polegać na nawykach, które mają wykształcone użytkownicy z Polski, musimy takie nawyki stworzyć od nowa. Dlatego wybrałem animację odbijania, ale po kolei, najpierw troszkę logiki dodawania i odejmowania klocków
 

 
Trochę mi napisanie tego kawałka kodu czasu zajęło, już tłumaczę o co chodzi. Dostajemy licznik, czyli który klocek ma się wyświetlać (numer klocka na stosie), tablicę naszych obiektów, animację, oraz czy animować tylko ostatni element.
Główny if, licznik jest większy od zera, tutaj kolejność warunków jest ważna, jeśli bym je zamienił, to spróbował bym sprawdzić widzialność obiektu na null-u. Następnie, jeśli licznik jest większy od 1 (powód znowu null), oraz animuj ostatni element ma wartość prawda, wtedy wywołuję na obiekcie znajdującym się poniżej stosu metodę czyść animację. Jeśli bym tego nie zrobił, animował bym też tamten poprzedni obiekt. Czyli opadał by mi cały stos, zamiast tylko ostatniego klocka. Dalej już łatwo, ustaw widzialność, ustaw Interpolator (o tym poniżej, będą obrazki 😉 i uruchom animację na obiekcie.
Główny else i pierwszy if w nim, sprawdzenie czy znowu nie wywołamy wyczyszczenia animacji na nieistniejącym obiekcie (główny else oznacza tutaj ukrywanie obiektów, czyli mamy stos i przemieszczamy się w dół). Następnie oczywiście niewidzialność i odwrócona animacja na obiekcie znajdującym się nad aktualnym licznikiem. Przy odwróconej interpolacji wspomogłem się stackOverflow, okazało się, że Android nie dostarcza możliwości prostego odwrócenia animacji.
 
Jak wygląda samo tworzenie animacji w androidzie? Ano tworzymy sobie xml-a z parametrami opisującymi naszą animację, np takiego:
 
 

 
Możemy tutaj wrzucić jeszcze scale i rotate. Czyli możemy poruszać, obracać, powiększać/pomniejszać, pokazywać/ukrywać nasze obiekty. Do tego dodać parametry, np opóźnienie startu, kiedy chcemy mieć animację sekwencyjną, czas trwania, pozycje na ekranie, itd.. To samo możemy uzyskać w kodzie javy w klasie, ale jakoś tak tutaj mi przejrzyściej 😉
 
Jeszcze dwa słówka o tym, jak tego użyć w klasie
 
 

Koniec dwóch słówek 😉
 
Przechodzimy do interpolatora, czyli sposobu w jaki nasza animacja ma się zachowywać. Wpisany do góry w xmlu to linear_interpolator. Klasyczny i nudny, ciągły ruch z tą samą szybkością przez cały czas, o tak to wygląda:
 
Prosty, płynny ruch, według mnie robotyczny, na pewno nie naturalny.
Spróbowałem więc następnego, nazywa się bounce i jak sama nazwa wskazuje, udaje odbijający się element. Hmmm jeśli rzucimy jakąś belkę na stos, to prawdopodobnie się odbije, wybrałem właśnie jego jako najbardziej naturalny, kojarzący się z rzeczywistością. Prezentuję:
Ładniutko, w momencie, w którym zamiast tej jednolitej belki będziemy mieli jakieś png, wydaje mi się, że będzie wyglądał w porządku. Na koniec sprawdziłem jeszcze jednego, nazywa się Overshot. Ja tam nazwał bym go plum, bo kojarzy mi się z wrzuceniem czegoś pływającego do wody 😉 Oceńcie sami:
Ciekawie wygląda, przyjmuje parametr pozwalający określić głębokość na jaką ma zejść 😉 Nie wymieniłem tutaj wszystkich interpolatorów są jeszcze np accelerate, decelerate, accelerate&decelerate.
Uff dobrnęliśmy do końca, chociaż tak naprawdę, możemy sobie stworzyć własny interpolator, i wydaje mi się, że to jeszcze nie wszystkie możliwości, jeśli chodzi o tworzenie animacji w Androidzie 😉 Chyba coś jeszcze na ten temat napiszę.
Ps. Dla osób startujących w konkursie dsp, zauważyłem, że ten konkurs sporo daje jeśli chodzi o tworzenie się społeczności. Jeśli trafiłeś tutaj w ramach konkursu, zapraszam na Slacka, toczą się tam naprawdę ciekawe rozmowy, i na bieżąco można otrzymywać recenzje swoich postów, kolejna motywująca rzecz 😉
Pozdrawiam!