Adăugarea de animație bazată pe fizică la aplicațiile Android. Crearea de animații de tranziție între Activitate în Android

În acest articol, vom analiza cum să animați elementele de interfață în Android. În acest caz, elementele de interfață înseamnă toți descendenții clasei View (o listă completă a descendenților poate fi găsită în documentația clasei View). Animația este o modalitate ușoară de a face o aplicație mai plină de viață :)

1. Să începem prin a crea un site de testare. Să facem o aplicație simplă cu un buton și o imagine în mijlocul ecranului. Nu voi da codul, este simplu, dacă este ceva, uitați-vă la surse (sunt la sfârșitul articolului).

2. În directorul /res/anim, creați un fișier anim.xml și scrieți acolo
< set xmlns:android=" http : // schemas.android.com /apk/res/android " android:shareInterpolator=" false " > < alpha android:fromAlpha=" 0.0 " android:toAlpha=" 1.0 " android:duration=" 1000 " />
Aceasta este descrierea animației pe care o vom aplica imaginii noastre. Ne vom uita la ceea ce se întâmplă aici mai detaliat mai jos, dar pentru moment îl vom copia doar într-un fișier.

3. Pentru a încărca o animație de la fișier xml folosit metoda statica clasa AnimationUtils
loadAnimation (context context, int id), Unde context este contextul actual și id- identificatorul resursei cu animație. Metoda returnează o instanță a clasei Animation.
Animație - o clasă abstractă pentru reprezentarea animației într-o aplicație.
Pentru ao aplica, instanța rezultată a clasei Animation este transmisă metodei
startAnimation(animație de animație) clasa View (și toți descendenții săi).

4. Să scriem în fișierul AnimationTestActivity.java:
clasă publică AnimationTestActivity extinde Activitatea ( imagine ImageView; Buton Button; Animation animație; @Override protected void onCreate(Bundle savedInstanceState) ( super .onCreate(savedInstanceState); setContentView(R.layout.main); imagine = (ImageView)findViewById(R. id.image); buton = (Button )findViewById(R.id.button); onClick(Vizualizare v) ( image.startAnimation(anim); //2 ) ) )
1) Citiți fișierul cu identificatorul R.anim.anim (care corespunde fișierului /res/anim/anim.xml) și obțineți o instanță a clasei Animation.
2) Făcând clic pe butonul, aplicăm animație imaginii.

5. Puteți rula aplicația noastră. Când apăsați butonul, imaginea va dispărea și apoi va începe încet să apară înapoi.

6. Acum să aruncăm o privire mai atentă asupra modului în care este creată animația într-un fișier xml.
Există 4 tipuri de animație:


  • alfa(transparență, vizibilitate)

  • scară(scalare)

  • roti(întoarce)

  • Traduceți(mișcare)

Pentru a crea animație, trebuie să descriem stările inițiale și finale ale obiectului, iar sistemul însuși va decide cum să treacă de la o stare la alta. În exemplul nostru
< alpha android:fromAlpha=" 0.0 " android:toAlpha=" 1.0 " android:duration=" 1000 " />
descriem animația alfa, adică schimbăm vizibilitatea obiectului. Setați starea inițială fromAlpha="0.0"(complet invizibil) și finit toAlpha="1.0"(pe deplin vizibile). Specificați durata animației duration="1000"(în milisecunde). Și orice altceva, adică cum să schimbi vizibilitatea unui obiect pentru a-l transforma din invizibil în vizibil într-o secundă, sistemul se face singur. Aceasta se calculează folosind interpolare- în matematică computațională, o modalitate de a găsi valori intermediare valori din setul discret disponibil de valori. Pentru fiecare animație puteți seta un interpolator
-AccelerateDecelerateInterpolator(@android:anim/accelerate_decelerate_int erpolator) - rata de schimbare este scăzută la început și la sfârșit și accelerează la mijloc

-AccelerateInterpolator(@android:anim/accelerate_interpolator) - rata de schimbare începe scăzută și apoi accelerează

-Antipolator(@android:anim/anticipate_interpolator) - modificările încep la reversul apoi mergi repede înainte

-Anticipate OvershootInterpolator(@android:anim/anticipate_overshoot_inte rpolator) - modificările încep în direcția opusă, apoi se deplasează rapid înainte și zboară deasupra valorii finale, apoi revin la valoarea finală

- BounceInterpolator(@android:anim/bounce_interpolator) - rata de schimbare crește la sfârșit

-CycleInterpolator(@android:anim/cycle_interpolator) - repetă animația de un număr specificat de ori. Rata de schimbare urmează o undă sinusoidală

-DecelerateInterpolator(@android:anim/decelerate_interpolator) - rata de schimbare scade la sfârșit

-Interpolator liniar(@android:anim/linear_interpolator) - rata de schimbare este constantă

-Depășirea interpolatorului(@android:anim/overshoot_interpolator) - modificările sar înainte și zboară deasupra valorii finale, apoi revin la valoarea finală

Interpolatorul este setat folosind atributul android:interpolator. De exemplu
android:interpolator="@android:anim/cycl e_interpolator". Valoarea implicită este LinearInterpolator.

7. Descrierea stărilor inițiale și finale
1) alfa (transparență, vizibilitate)
- Android: de la Alpha- valoarea inițială a transparenței. 0,0 - complet transparent (invizibil), 1,0 - complet opac (vizibil)
- android:toAlpha- valoarea finală a transparenței

2) scară
- android:fromXScale- valoarea inițială a scalei de-a lungul axei X (unde dimensiunea curentă corespunde valorii 1.0)
- android:toXScale- valoarea finală a scalei de-a lungul axei X
- android:de la YScale- valoarea inițială a scării de-a lungul axei Y (unde dimensiunea curentă corespunde valorii 1.0)
- android:toYScale- valoarea finală a scalei de-a lungul axei Y
- android:pivotX- coordonata x a punctului, care va rămâne neschimbată după scalare
- android:pivotY- coordonata y a punctului, care va rămâne neschimbată după scalare

Valori posibile pentru pivotX și pivotY:
în pixeli în raport cu marginea din stânga (sau de sus pentru coordonatele Y) a elementului (de exemplu, „5”)
ca procent în raport cu marginea din stânga (sus) (de exemplu, „5%”)
ca procent față de marginea din stânga (sus). element părinte(de exemplu „5%p”)

De exemplu, dacă pivotX=0, pivotY=0 (care corespunde colțului din stânga sus al elementului), atunci scalarea va redimensiona elementul în jos și la dreapta. Dacă pivotX=50%, pivotY=50%, atunci punctul se află în centrul elementului și dimensiunea se schimbă în toate direcțiile, în timp ce centrul va rămâne într-un punct.

3) roti (întoarce)
- Android: de la Degrees- Valoarea inițială a unghiului de rotație (în grade, valoare negativă posibilă)
- Android:toDegrees- valoarea finală a unghiului de rotaţie
- android:pivotX- coordonatele x ale centrului de rotație.
- android:pivotY- coordonata y a centrului de rotație.
Valori posibile ale pivotX și pivotY ca în animația la scară

4) traduce (muta)
- android:de la XDelta- coordonata x a punctului de plecare al mișcării. Valori posibile:
în pixeli în raport cu poziția inițială (de exemplu „5”)
ca procent în raport cu lățimea elementului (de exemplu, „5%”)
ca procent în raport cu lățimea elementului părinte (de exemplu „5%p”)
- android:toXDelta- coordonata x punctul final circulaţie
- android:de la YDelta- coordonata y a punctului de plecare al mișcării
- android:toYDelta- coordonata y a punctului final al mișcării

8. Opțiuni suplimentare
Există, de asemenea, atribute comune tuturor celor patru tipuri de animație, dintre care cele mai utile sunt:
- android: durată- durata animației (în milisecunde)
- android:interpolator- definește interpolatorul pentru animație
- android:repeatCount- numărul de repetări suplimentare de animație. Exact altele, adică animația se va executa oricum o dată. Valoarea implicită este „0” - aceasta înseamnă că animația va fi executată o singură dată. O valoare de „1” înseamnă că animația va rula de două ori (o dată cea principală și o dată cea secundară). Valoarea „-1” sau „infinit” înseamnă repetiție nesfârșită.
- android:repeatMode- determină comportamentul animației când a ajuns la sfârșit, iar parametrul repeatCount nu este egal cu 0. Există două valori: „restart” - animația începe din nou și „reverse” - animația va merge în ordine inversă .
- android:startOffset- întârziere înainte de începerea animației (în milisecunde)

9. Combinarea mai multor animații
Puteți aplica mai multe tipuri de animații unui element în același timp. De exemplu, dacă scriem:
< set xmlns:android=" http : // schemas.android.com /apk/res/android " > < alpha android:fromAlpha=" 0.0 " android:toAlpha=" 1.0 " android:duration=" 1000 " /> < rotate android:fromDegrees=" 0 " android:toDegrees=" 360 " android:pivotX=" 50% " android:pivotY=" 50% " android:duration=" 1000 " />
Imaginea va schimba transparența în 1 secundă (de la complet transparentă la opac) și, în același timp, se va roti la 360 de grade.

Animațiile pot fi setate la durate diferite, de exemplu, să setăm durata=5000 pentru rotirea animației. Acum imaginea se va roti mult mai încet, iar transparența se va schimba în continuare într-o secundă.

Prin utilizarea startOffset, puteți face animațiile secvențiale. Adăugați atributul de rotație startOffset="1000"(adică vom face o întârziere egală cu durata primei animații). Acum imaginea va deveni mai întâi vizibilă în 1 secundă, apoi se va roti doar la 360 de grade.

Mai multe animații pot fi combinate în seturi folosind eticheta. O astfel de etichetă va fi întotdeauna în fișier și este eticheta rădăcină. Puteți seta următoarele atribute pentru un set:
- durată(durată), Mod Repetare(mod repetare) - aceste atribute vor fi aplicate fiecărei animații din set
- interpolator- defineşte interpolatorul de animaţie şi shareInterpolator- acest interpolator va fi aplicat fiecărei animații din set ( valori posibile"adevarat si fals")
- startOffset(întârziere) - întârziere pentru întregul set de animații.
Din păcate, atributul nu poate fi aplicat setului repeatCount, adică repetarea unui set de animații de mai multe ori nu va funcționa.
Seturile pot fi de orice cuibărit.

10. Crearea de animație fără xml
Animația poate fi creată fără utilizarea xml, direct în codul programului. Pentru aceasta, sunt folosite clasele descendente Animation:
1) AlphaAnimation pentru a crea animație alfa. Constructorul clasei arată ca
AlphaAnimation (float fromAlpha, float toAlpha) unde fromAlpha și toAlpha sunt valorile inițiale și, respectiv, finale ale transparenței (de la 0,0 la 1,0)

11. Să creăm o animație în cod care, atunci când apăsați un buton, va roti imaginea cu un unghi aleatoriu (de la 0 la 360) și o va mări la o dimensiune aleatorie (nu mai mult de două ori). În acest scop am adăugat un alt buton randomButton
randomButton.setOnClickListener(new OnClickListener() ( @Override public void onClick(View v) ( Aleatoriu aleatoriu = nou Aleatoriu (); //1 RotateAnimation rotire = nou RotateAnimation (0, (float )random.nextInt(360), Animație. RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f; //2 rotate.setDuration(1000); ); //6 float size = random.nextFloat() + 1.0; //7 ScaleAnimation scale = new ScaleAnimation(1.0f, size, 1.0f, size, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF , 0.5f); //8 scale.setDuration(1000) ; );
1) Creați un obiect Random pentru a genera numere aleatorii. Puteți citi mai multe despre Random în documentație acum ne interesează metodele int nextInt(int n) - generarea unui număr întreg în intervalul de la 0 la n. Și se generează metoda float nextFloat(). numar real de la 0 la 1.
2) Creați o animație de rotație. Unghiul de început = 0, unghiul de final = Număr aleatoriu de la 0 la 360. Animație.RELATIVE_TO_SELF înseamnă că vom indica punctul central de rotație ca procent în raport cu lățimea elementului. Nu uitați că valoarea 1,0 corespunde la 100%, ceea ce înseamnă că 0,5f este 50%. Aceasta înseamnă că centrul de rotație va fi în mijlocul imaginii.
3) Setați durata animației la 1000 de milisecunde (aceasta este de 1 secundă)
4) Definim modul de repetitie ca Animation.REVERSE, adica la repetarea animatiei, vom merge in ordine inversa.
5) Setați numărul de repetări suplimentare = 1. Aceasta înseamnă că animația se va repeta de două ori, o dată în ordine înainte și o dată în sens invers.
6) Metoda lung computeDurationHint() calculează cât va dura animația în total. Există o metodă getDuration(), dar pur și simplu returnează valoarea duratei pe care o setăm cu metoda setDuration(). În cazul nostru, setăm valoarea duratei la 1000, iar metoda getDuration() va returna 1000 și nu va ține cont de faptul că animația se va repeta de două ori, ceea ce înseamnă că va dura de fapt 2000 de milisecunde. Metoda computeDurationHint() va calcula durata luând în considerare reîncercări și întârzieri.
7) Calculam dimensiune nouă Poze. Valoarea 1.0 este scara actuală a imaginii, deci valoarea 2.0 înseamnă că imaginea este dublată. Generăm un număr de la 0.0 la 1.0 și adăugăm 1, ceea ce înseamnă că obținem un număr de la 1.0 la 2.0
8) Creați o animație de scalare de la dimensiunea actuală a imaginii la un număr generat aleatoriu de la 1,0 la 2,0
9) Setați o întârziere egală cu durata totală a animației de rotație. Astfel încât a doua animație să înceapă imediat după sfârșitul primei
10) Creați un set de animații.
11) Adăugați două animații create la set
12) Aplicați un set de animații imaginii

12. O altă metodă interesantă a clasei de animație
setAnimationListener (ascultător de animație.AnimationListener)- setează un ascultător pentru modificările stării animației. Interfața Animation.AnimationListener definește următoarele metode:
onAnimationStart (animație de animație)- apelat când începe animația
onAnimationRestart (animație de animație)- apelat când animația se repetă
onAnimationEnd(animație de animație)- sunat la sfârșitul animației

De exemplu:
anim = AnimationUtils.loadAnimation(this, R.anim.anim); anim.setAnimationListener(new AnimationListener () ( @Override public void onAnimationEnd(Animation animation) ( Log.d("MY" , "animation final" ); ) @Override public void onAnimationRepeat(animation animation) ( Log.d("MY") " , "repetare animație" ); ) @Override public void onAnimationStart(animație animație) ( Log.d("MY" , "animation start" ); ) ));
Nu facem nimic util atunci când schimbăm starea animației, doar o scriem în jurnal.

Asta e tot. Ți-am spus elementele de bază, e mai bine să înveți restul prin experimente :)

Sursele pot fi descărcate aici

De ceva timp în Android este posibil să se utilizeze resurse vectoriale în loc de felii png. Această oportunitate a apărut odată cu lansarea Android 5.0 Lollipop și API 21. Pentru mai multe versiuni anterioare sistem, putem folosi AppCompat (biblioteca de compatibilitate), datorită căruia un vector static va funcționa cu API 7 (Android 2.1) și unul animat cu API 11 (Android 3.0 Honeycomb).

Resursele vectoriale, spre deosebire de tăierea convențională, ocupă de aproximativ 10 ori mai puțin spațiu. Nu este nevoie să adaptați grafica la diferite densități de ecran. În plus, puteți reutiliza resursa în diferite contexte, dimensiuni și culori.

Pentru alții avantaj important este capacitatea de a adăuga animație. Da, desigur, animația poate fi făcută folosind png — de exemplu, animația sprite, dar o astfel de animație va ocupa de zeci de ori mai mult spațiu, ținând cont de suportul pentru toate rezoluțiile.

Vector pentru Android?

Înainte de a începe să creați elemente vectoriale, trebuie să înțelegeți ce este un vector pe Android. Înțelegerea structurii este foarte importantă pentru că în prezent nu există instrumente pentru creație convenabilăși controlul vizual al animației.

Din păcate (sau din fericire), nu puteți folosi fișiere svg direct în Android, cel puțin fără a utiliza biblioteci terțe. Motivul este foarte simplu și este că formatul SVG este foarte complex și bogat în capacități, iar susținerea unei astfel de funcționalități bogate este complexă și nu practică pentru lucruri atât de simple precum pictogramele și nu uitați de problema performanței și a compatibilității. De aceea, în Android folosesc un format mai simplu, care, totuși, este în multe privințe similar cu svg.

Grafica vectorială este reprezentată ca două clase, VectorDrawable și AnimatedVectorDrawable. Din numele claselor este clar că prima este responsabilă pentru un vector static, iar a doua pentru animația acestuia. Clasele sunt descrise de o resursă XML obișnuită.

Mai întâi, să ne uităm la un VectorDrawable, care are următoarea structură:

În element conține parametri pentru înălțimea și lățimea obiectului. Există un element în interior care poate conţine elemente ȘI precum și alte grupuri. În parametrii elementului sunt indicate informații despre transformare (offset, scară și unghi) și numele pe care îl vom folosi pentru a aplica animația. Elemente ȘI descrie geometria și culoarea unui obiect.

Pentru a adăuga animație, folosim clasa ObjectAnimator, pe care o aplicăm pur și simplu obiectelor VectorDrawable. Putem aplica animația atât unui grup general, cât și unui anumit grup Animația poate fi manipulare simplă parametrii obiectului și transformarea complexă.

Anterior, pentru a implementa animația într-o aplicație, era necesar să se folosească cel puțin 3 fișiere xml: 1 fișier pentru VectorDrawable care trebuie animat, altul pentru animatorul care descrie animația și ultimul fișier care combină direct animatorul și VectorDrawable. . Cu cât animația este mai complexă, cu atât trebuiau create mai multe fișiere, ceea ce ducea adesea la confuzie.

La Google I/O 2016, a fost introdus un nou format - pachetul XML. Vă permite să descrieți animația vectorială într-un singur fișier.

Exemplu de pachet XML

În esență, suntem cu toții informatie necesara plasat în AnimatedVectorDrawable. Este foarte ușor să asamblați un astfel de fișier, piesele sunt evidențiate în imagine, care sunt pur și simplu decupate din resursele corespunzătoare și introduse între etichetele speciale aapt.

Pregătirea unui vector pentru Android

Mai întâi avem nevoie de oricine editor grafic, care poate scoate un fișier svg. Din fericire, există foarte multe dintre ele: Photoshop, Illustrator, Sketch, Inkscape, Designer de afinitate etc.

În timp ce creați imagine vectorială trebuie să folosești cel mai mult instrumente de bază, deoarece umbrele și alte filtre pur și simplu nu vor funcționa.

De exemplu, am făcut-o pictogramă simplă castel și l-a împărțit în două forme (grupuri) pentru animație ulterioară. Îl salvăm ca svg și asigură-te că verificăm corectitudinea exportului. Foarte des apar probleme cu lovitura și cuibărirea excesivă a obiectelor. De regulă, încercați să combinați totul într-un singur obiect cât mai mult posibil și traduceți accidentul vascular cerebral în formă (contur).

Convertiți SVG în XML

Există mai multe moduri de a converti un fișier svg în xml.

Prima modalitate este să faci totul manual. Acest lucru, desigur, nu este foarte convenabil, dar nu este nimic complicat aici. Doar transferați bucăți din svg în xml folosind nume corecte parametrii. Mai jos am evidențiat piese care sunt aproape complet identice.

Al doilea mod — În Android Studio are un instrument Vector Asset Studio care vă permite să traduceți automat un fișier SVG în XML. Puteți selecta resurse din biblioteca de pictograme sau puteți specifica propriul fișier SVG. Datorită previzualizării, puteți evalua imediat corectitudinea exportului. Mânca setări utile.

A treia modalitate este de a folosi instrumente online, De exemplu

La ribot ne pasă să creăm frumos și experiență semnificativă pentru persoanele în care mișcarea joacă un rol important.

După ce am asistat la o discuție inspirată la Droidcon Londra, am decis să aprofundez elementele de mișcare ale Android. Având în vedere acest lucru, am compilat toate constatările mele pentru a ajuta dezvoltatorii și designerii să știe cât de ușor este să adăugați mișcare frumoasă la aplicațiile Android.

Dacă doriți să încercați să realizați singuri aceste animații, fiecare dintre aceste exemple este împachetat într-o aplicație Android pe Github.

Iubesc mișcarea, nu numai că mărește interacțiunea, dar dă imediat capul. Gândiți-vă la aplicațiile pe care le utilizați și la grafica în mișcare, în special la cât de frumos, ușor, gratuit și natural arată.

Falcon Pro: Chiar și mișcările subtile pot face o diferență uriașă în experiența utilizatorului

Acum compară-le cu aplicațiile pe care le iubești și care nu trezesc aceleași sentimente.

Mediu: Oricât de mult îmi place aplicația Medium, chiar îi lipsește mișcarea în zonele pe care merită să o aibă.

Totul este în detalii

Putem folosi aceste efecte de mișcare în diferite moduri:

  • Transferați utilizatori prin contextul de navigare
  • Întăriți ierarhia elementară
  • Explicați modificările dintre componentele afișate pe ecran

Scopul acestui articol este să vă arate cât de ușor este să implementați mișcarea în aplicațiile dvs. unde poate aduce beneficii semnificative - așa că să începem.

Feedback la atingere

Furnizarea de feedback atunci când utilizatorul atinge ecranul ajută la comunicarea într-un mod vizual, astfel încât să aibă loc interacțiunea. Aceste animații nu ar trebui să distragă atenția utilizatorului, dar ar trebui să ofere distracție, claritate și să încurajeze explorarea ulterioară.

Cadrul Android oferă o stare de ondulare pentru acest strat de feedback, care poate fi folosit pentru a seta fundalul animației la una dintre următoarele:

Android:attr/selectableItemBackground - Afișează un efect de ondulare în limitele imaginii.

Pulsația începe în punctul de contact, umplând fundalul imaginii prezentate

?android:attr/selectableItemBackground Borderless- Afișează un efect de pulsație care depășește limitele imaginii prezentate.

Un efect de pulsație circulară începe la punctul de contact, umplând o rază dincolo de imaginea prezentată

Vizualizați animator de proprietate

View Property Animator a fost introdus la nivelul API 12, care vă permite să efectuați simplu și eficient operațiuni de animație (în paralel) pe mai multe proprietăți de imagine folosind o singură instanță Animator.

Aici fac animații pe toate proprietățile prezentate mai jos.

alpha() - Setează valoarea alfa pentru a face animația
ScaleX() & ScaleY() - Echilibrează vizualizarea pe axa X și/sau Y
translationZ() - Traduce vizualizarea pe axa sa Z
setDuration() - Setează durata animației
setStartDelay() - Setează întârzierea animației
setInterpolator() - Setează interpolarea animației
setListener() - Setează un ascultător să știe când începe, se termină, se repetă sau se anulează animația.
Notă: Când ascultătorul a fost instalat în această imagine și dacă efectuați alte animații în același punct și nu doriți să utilizați această funcție sună din nou, atunci ar trebui să setați ascultătorul la NULL.

Acest lucru este, de asemenea, simplu și ordonat de implementat programatic:

mButton.animate():

TraducereZ(10f)

SetInterpolator(nou FastOutSlowInInterpolator())

SetStartDelay(200)

SetListener(nou Animator.AnimatorListener() (

public void onAnimationStart(animația animatorului) ( )

public void onAnimationEnd(animația animatorului) ( )

public void onAnimationCancel(animația animatorului) ( )

public void onAnimationRepeat(animația animatorului) ( )

Notă: de fapt, nu trebuie să apelăm start() pe generatorul nostru de animație, deoarece animația pornește automat de îndată ce oprim declararea animației în același timp. Dacă acesta este cazul, atunci animația nu va începe până la următoarea actualizare din coada de evenimente de instrumentare a interfeței.

Notă: Pentru a asigura compatibilitate inversă, puteți folosi clasa ViewCompat pentru a implementa ViewPropertyAnimator de la Android API versiunea 4 și mai sus.

La fel ca View Property Animator, Object Animator ne permite să animam diverse proprietăți ale imaginii țintă (atât în ​​cod, cât și în resursele fișierului XML). Cu toate acestea, există câteva diferențe:

Object Animator permite ca o animație să existe doar într-o singură stare, de exemplu, o scară X urmată de o scară Y
Cu toate acestea, permite animației să existe în starea sa normală, cum ar fi culoarea primului plan a imaginii.
Folosind proprietăți sau stări personalizate pentru a anima imaginea la scară și pentru a schimba culoarea primului plan, putem realiza următoarele:

Folosind Proprietatea personalizată, putem crea o singură instanță a Object Animator apelând ObjectAnimator.ofInt() unde afirmăm:

Vizualizare - Vizualizare pentru a aplica animația
Proprietate - Proprietate pentru animație
Culoare inițială - Culoarea din care vizualizare animațieîncepe
Culoare țintă - Culoarea cu care imaginea asta trebuie să prindă viață
private void animateForegroundColor(@ColorInt final int targetColor) (
Animator ObjectAnimator =
ObjectAnimator.ofInt(YOUR_VIEW, FOREGROUND_COLOR, Color.TRANSPARENT, targetColor);
animator.setEvaluator(nou ArgbEvaluator());
animator.setStartDelay(DELAY_COLOR_CHANGE);
animator.start();
}
Apoi setăm evaluatorul (folosim ArgbEvaluator deoarece facem animația între valorile de culoare), setăm întârzierea și pornim() animația.

Instanțiăm ObjectAnimator folosind ofFloat() deoarece nu animăm valori întregi atunci când lucrăm cu dimensiunile imaginii
În loc de proprietate personalizată, folosim proprietățile imaginii - atât View.SCALE_X, cât și View. SCALE_Y
private void resizeView() (
final float widthHeightRatio = (float) getHeight() / (float) getWidth();
resizeViewProperty(View.SCALE_X, .5f, 200);
resizeViewProperty(View.SCALE_Y, .5f / widthHeightRatio, 250);
}
private void resizeViewProperty(Proprietate proprietate
float targetScale,
int durationOffset) (
ObjectAnimator animator = ObjectAnimator.ofFloat(this, property, 1f, targetScale);
animator.setInterpolator(nou LinearOutSlowInInterpolator());
animator.setStartDelay(DELAY_COLOR_CHANGE + durationOffset);
animator.start();
}
În cele din urmă, trebuie să ne animam imaginea redimensionată în afara ecranului. În acest caz, folosim AdapterViewFlipper pentru a ne adapta imaginile pe care le animam în afara ecranului. Folosind acest lucru înseamnă că putem apela showNext() pe instanța ViewFlipper și va anima imagini în afara ecranului folosind animația pe care am definit-o. Apoi, următoarea imagine va prinde automat viață pe ecran, folosind și animația de intrare pe care am definit-o și noi.

Interpolatoare

Un interpolator poate fi folosit pentru a determina rata de schimbare pentru o animație, ceea ce înseamnă că viteza, accelerația și comportamentul animației pot fi modificate. niste tipuri variate, interpolatoarele disponibile și diferențele dintre unele dintre ele sunt subtile, așa că vă sugerez să le încercați pe acest dispozitiv.

  • Fără interpolator - Vederea prinde viață fără variații ale ratei de schimbare
  • Rapid - În afara liniei - În interior

Imaginea începe animația și se termină cu mișcare liniară

  • Rapid - Incet - Inauntru

Imaginea începe rapid animația și încetinește spre final

  • Linear - Lent - În interior

Imaginea începe cu mișcări liniare și încetinește spre final

  • Accelerație - Decelerație

Imaginea începe să accelereze la începutul animației și încetinește treptat pe măsură ce se termină.

  • Accelerează - imaginea accelerează treptat până când animația se termină
  • Frânare - Imaginea încetinește treptat până la sfârșitul animației
  • Lead - Imaginea începe cu o ușoară rotație a animației specificate înainte de a se muta într-o manieră standard
  • Anticipați - Omiteți - La fel ca Plumb, dar mișcarea de „tragere înapoi” care apare în timpul animației este puțin mai exagerată
  • Jumping Interpolator - Imaginea prinde viață cu un efect de „săritură” înainte de a ajunge la linia de sosire
  • Interpolator liniar - O imagine prinde viață de la început până la sfârșit cu o mișcare liniară și lină
  • Sarirea interpolatorului - imaginea „revitalizează” exagerarea unei valori date, retrăgându-se înapoi la valoarea necesară

Animație circulară

Animația CircularReveal folosește un cerc decupat fie pentru a dezvălui, fie pentru a ascunde un grup de elemente interfața cu utilizatorul. Pe lângă faptul că ajută la asigurarea continuității vizuale, este și o interacțiune plăcută care ajută la îmbunătățirea acesteia cu utilizatorul.

După cum se arată mai sus, începem prin a folosi View Property Animator pentru a ascunde butonul Floating Action înainte de a începe să animam animația în fața ochilor noștri. Configurarea cercului nostru de revigorare necesită definirea doar a câtorva atribute:

  • startView - vizualizarea de la care va porni CircularReveal (adică vizualizarea comprimată)
  • centerX - Coordonatele centrale pentru axa X atunci când este apăsat
  • centerY- Coordonatele centrale pentru axa Y atunci când este apăsat
  • targetView - Vederea de creat
  • finalRadius - Raza de tăiere a cercului, egală cu ipotenuza valorilor noastre - centerX și centerY

int centerX = (startView.getLeft() + startView.getRight()) / 2;
int centerY = (startView.getTop() + startView.getBottom()) / 2;
float finalRadius = (float) Math.hypot((dublu) centruX, (dublu) centruY);
Animator mCircularReveal = ViewAnimationUtils.createCircularReveal(
targetView, centerX, centerY, 0, finalRadius);

Tranziții de fereastră

Personalizarea tranzițiilor utilizate pentru a naviga între tranzacții permite conexiuni vizuale mai puternice între stările aplicației. În mod implicit, putem configura următoarele tranziții:

  • input - Definește modul în care imaginile tranzacției intră în scenă
  • exit - Determină modul în care imaginile tranzacției ies din scenă
  • enter din nou - Definește modul în care o tranzacție va intra din nou după ce a ieșit anterior
  • elemente partajate - Definește modul în care imaginile de tranziție sunt schimbate între tranzacții

Ca și în cazul API Level 21, au apărut și au fost introduse mai multe tranziții noi:

Tranziția explozivă permite imaginilor să iasă din toate părțile ecranului, creând un efect exploziv atunci când sunt apăsate.

Efectul de rafală funcționează foarte bine pe planșele bazate pe grilă.

Acest efect este ușor de implementat - pentru început, trebuie să creați următoarea tranziție în directorul RES res/tranziție.

android:duration="300“/>

Tot ce am făcut aici:

  • Tranziție explozivă anunțată
  • Setați durata la 300 de milisecunde

Sau programatic:

Transition explode = TransitionInflater.from(this).inflateTransition(R.transition.explode);
getWindow().setEnterTransition(explode);

Slide

Tranziția prin diapozitiv vă permite să introduceți sau să ieșiți dintr-o tranzacție din partea dreaptă sau din partea de jos a ecranului. Deși este posibil să fi ajuns la asta mai devreme, asta noua tranzitie este mult mai flexibil.

Tranziția de diapozitiv vă permite să alunecați secvențial în imagini copil

Această tranziție este probabil să fie obișnuită la schimbarea tranzacțiilor, mi-a plăcut în special slide-ul potrivit datorită stării sale asemănătoare lichidului. Din nou, acest lucru este ușor de făcut:

android:interpolator=„@android:interpolator/decelerate_cubic“
android:slideEdge="end“/>

Aici noi:

  • Se anunță tranziția de diapozitiv
  • Setați slideEdge de tranziție să se termine acolo (pe dreapta), astfel încât diapozitivele să meargă la dreapta - slide-ul de jos ar trebui să fie setat în partea de jos

Decolorare

O tranziție de estompare vă permite să treceți la o tranzacție intern sau extern folosind efectul de estompare.

Tranziția de decolorare este simplă, deși tranziția de decolorare este plăcută ochiului.

Crearea acestuia este chiar mai ușoară decât tranzițiile anterioare:

android:duration="300“/>

Aici noi:

  • Anunțăm tranziția care se estompează
  • Setați durata la 300 de milisecunde

Optimizarea tranziției

În ciuda experimentelor, am găsit câteva abordări care pot ajuta la îmbunătățirea efectelor de tranziție menționate mai sus.

Permite tranzițiile conținutului ferestrei- trebuie să activați următorul atribut în temele care moștenesc din tema materialului:

Adevărat

Activați/dezactivați tranzițiile de potrivire- La tranziție, poate exista o întârziere în care o acțiune așteaptă ca alta să își finalizeze tranziția înainte de a putea începe propria. În funcție de cazul de utilizare, tranzițiile vor arăta în general mai fluide și mai naturale dacă activați aceste atribute:

Adevărat

Excluderea imaginilor din tranziții- Uneori este posibil să nu dorim să creăm tranziții pentru toate imaginile tranzacțiilor noastre. Am descoperit că, în majoritatea cazurilor, bara de stare și bara de instrumente au cauzat erori de tranziție. Din fericire, putem exclude anumite specii care au fost incluse în tranzițiile noastre:

android:duration="200“>




Bara de instrumente și bara de acțiuni- Când trecem între acțiuni folosind Bara de acțiuni la utilizarea Barei de instrumente (și invers), uneori am constatat că tranziția nu a fost întotdeauna lină. Pentru a remedia acest lucru, m-am asigurat că cele două activități implicate în tranziție foloseau aceeași componentă.

Durata tranziției- Nu doriți ca utilizatorul să aștepte prea mult, dar nici nu doriți să creați componente care să apară cu viteza luminii. Aceasta depinde de tranziția pe care o utilizați, așa că cel mai bine este să experimentați, dar am constatat că o durată de 200-500 ms funcționează în majoritatea cazurilor.

Elemente comune de tranziție

Elementele de tranziție partajate vă permit să animați tranzițiile între imaginile partajate într-o tranzacție, creând tranziții mai plăcute și oferind utilizatorului o mai bună perspectivă a călătoriei sale.

Aici, imaginea din prima noastră acțiune este scalată și tradusă în imaginea antet în a doua noastră acțiune

În layout-urile noastre, trebuie să asociem orice imagini comune folosind atributul transitionName - aceasta stabilește relații de tranziție între imagini. Mai jos sunt imagini generale din animația de mai sus:

Acestea sunt imagini partajate, ceea ce înseamnă că vor prinde viață între ele în timpul tranzițiilor de acțiune

Pentru a trece între acestea două, începem prin a declara numele tranziției comune, făcută folosind atributul transitionName în layout-urile XML.




android:transitionName="@string/transition_view“/>



android:id="@+id/view_shared_transition"
android:transitionName="@string/transition_view“/>
android:id=“@+id/view_separator“/>
android:id=“@+id/text_detail“/>
android:id=“@+id/text_close“/>

Odată ce s-a făcut acest lucru, creăm un obiect Pair la pasul 1) care conține imaginea noastră de tranziție și transiția sa. Apoi îl transmitem la opțiuni de tranzacție de exemplu, cum ar fi (ActivityOptionsCompat), astfel încât ambele activități să cunoască componentele comune. De acolo vom începe tranzacția noastră, prin opțiunea exemplu:

Participanți pereche = pereche nouă<>(mSquareView, ViewCompat.getTransitionName(mSquareView));
ActivityOptionsCompat transitionActivityOptions =
ActivityOptionsCompat.makeSceneTransitionAnimation(
SharedTransitionsActivity.this, participanți);
ActivityCompat.startActivity(SharedTransitionsActivity.this,
intentie, transitionActivityOptions.toBundle());

Separarea acestor imagini în timp ce tranziția are loc într-adevăr ajută la finalizarea tranziției.

Iată trecerea între aceste două imagini, dar cum rămâne cu imaginile din actul al doilea care alunecă de jos?

(Cei din stanga)

Ma bucur ca ai intrebat! Acest lucru este, de asemenea, ușor de realizat, după cum se arată mai jos:

Slide slide = slide new(Gravity.BOTTOM);
slide.addTarget(R.id.view_separator);
slide.addTarget(R.id.text_detail);
slide.addTarget(R.id.text_close);
getWindow().setEnterTransition(slide);
După cum puteți vedea, creăm un nou șablon de diapozitiv de tranziție adăugând vederi țintă pentru tranziție și setând diapozitivul ca tranziție de intrare a tranzacției.

Tranziții personalizate

Avem, de asemenea, capacitatea de a ne crea propriile tranziții folosind oricare dintre animațiile din API-ul pe care l-am acoperit până acum. De exemplu, putem duce tranzițiile elementului partajat cu un pas mai departe pentru a deveni o imagine de tranziție - acest lucru poate fi util atunci când dorim să afișăm casete de dialog (sau imagini pop-up similare), așa cum se arată mai jos:

Această mișcare ajută la direcționarea atenției utilizatorului între stările componente

Să aruncăm o privire rapidă la ce se întâmplă aici:

  • Începem prin a crea un SharedTransition, trecând în starea apăsată împreună cu numele tranziției pentru a face referire la componenta partajată
  • Apoi creăm o instanță ArcMotion, aceasta ne permite să creăm un efect de mișcare curbă atunci când trecem între două imagini
  • Apoi extindem ChangeBounds pentru a crea o tranziție personalizată și a transforma cele două forme (avem o clasă separată pentru buton și FAB). Aici trecem peste diverse metode din clasă astfel încât să putem anima proprietățile necesare. Vom folosi un ViewPropertyAnimator pentru a anima transparența imaginilor de dialog, un ObjectAnimator pentru a anima imaginile între cele două culori și un exemplu de AnimatorSet, astfel încât să putem anima ambele efecte împreună.

Vector animat al coeficientului de intrare

Începând cu versiunea API 21 (Lollipop), AnimatedVectorDrawable poate fi folosit pentru a anima proprietățile VectorDrawable pentru a obține o animație a desenabilului.

Acum este ușor să faci mai multe tipuri variate animație pe coeficientul de intrare

Dar cum facem asta? Ei bine, să aruncăm o privire la asta:

Este format din mai multe diverse fișiereși începem prin a crea cele două fișiere vectoriale separate, fiecare având câteva proprietăți:

  • Înălțime și lățime - Mărimea reală a imaginii vectoriale
  • Înălțimea și lățimea ferestrei - Declara dimensiunea pânzei virtuale pe care sunt desenate traseele vectoriale
  • Nume grup - Declarați grupul căruia îi aparține piesa
  • Pivot X și Y - Declarați pivotul utilizat pentru scara grupului și rotație
  • Traiectoria culorii Umplere-Culoare umplere cale vectorială
  • Path Data - Declarați datele căii vectoriale utilizate pentru a desena vectorul

Notă: Toate proprietățile linkului sunt stocate într-un fișier linie comun, care ajută la menținerea elementelor organizate și ordonate.

android:height="56dp"
android:width="56dp"

android:viewportWidth="24.0“>

android:pivotX="12"
android:pivotY="12“>

android:pathData="@string/path_add“/>

Vectorul este generat din fișierul nostru ic_add.xml (mai jos)

android:height="56dp"
android:width="56dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0“>
android:name=“@string/groupAddRemove“
android:pivotX="12"
android:pivotY="12“>
Android:fillColor="@color/stroke_color“
android:pathData="@string/path_remove“/>

Vectorul este generat din fișierul nostru ic_remove.xml (mai jos)

Apoi declarăm fișierele Animated Vector Drawable, care setează atât Vector Drawable, cât și animațiile folosite pentru fiecare stare de „întindere” (Add sau Remove). Privind vectorul de animație adăugat sau eliminat, declarăm ținta:

Animație de la o stare la alta
Animație de rotație a coeficientului introdus

android:drawable="@drawable/ic_add“>
android:nume=“@string/add“
android:animation="@animator/add_to_remove“ />
android:name=“@string/groupAddRemove“
android:animation=“@animator/rotate_add_to_remove“ />

Apoi trebuie să creăm fiecare dintre fișierele menționate în aceste scopuri.

Modificarea stării coeficientului introdus

În add_to_remove.xml folosim ObjectAnimator pentru a transforma formele folosind următoarele proprietăți:

  • PropertyName - Proprietate animație
  • valueFrom- Valoarea inițială pentru calea vectorială
  • valueTo- Valoarea țintă pentru calea vectorială
  • Duration - Durata animației
  • interpolator - Interpolator folosit pentru animație
  • ValueType - Tipul de valoare pe care îl animam

xmlns:android="//schemas.android.com/apk/res/android“
android:propertyName=“pathData“
android:valueFrom="@string/path_add“
android:valueTo=“@string/path_remove“

android:interpolator=„@android:interpolator/fast_out_slow_in“
android:valueType=“pathType“ />

Rotiți formularul

Folosim o abordare similară pentru a roti forma folosind proprietatea de rotație și magnitudine:

xmlns:android="//schemas.android.com/apk/res/android“
android:propertyName=„rotație“
android:valueFrom="-180"
android:valueTo=“0“
android:duration="@integer/duration“
android:interpolator="@android:interpolator/fast_out_slow_in“ />
Animația inversă (de la Eliminare la Adăugare) funcționează la fel, doar cu valorile de animație inversă.

Vectorul nostru de coeficient de intrare animat finalizat arată grozav, nu-i așa!

Si in concluzie…

Deși doar zgârie suprafața, sper că acest articol a oferit o perspectivă asupra modului în care puteți crea o mișcare semnificativă în aplicațiile dvs. Aștept cu nerăbdare să învăț cum le pot împinge mai departe și să îmbunătățesc modul în care arată și se simt designurile mele.

Dacă v-a plăcut acest articol, vă rugăm să faceți clic pe „Recomandă”!

Mi-ar plăcea să aud părerile voastre despre asta și despre unde folosiți aceste animații - vă rugăm să lăsați o recenzie sau să mă scrieți pe Twitter!

  • Dezvoltare Android
  • Începând cu Android 4.4, dezvoltatorii au adăugat instrument suplimentar pentru a crea animații - Transitions Framework. Inițial, a fost destinat să creeze animații de schimbare a stării unei aplicații prin manipularea mai multor vizualizări. CU Lansare Android 5.0, setul de animații disponibile pentru utilizare a fost extins pentru a corespunde conceptului de Material Design introdus în același timp.

    Transitions Framework vă permite să creați rapid și fără durere diverse animații. Prin urmare, în procesul de lucru la iFunny, a fost imposibil să ignorați acest set de instrumente. Cititorii sunt invitați să caz special folosind Transitions API - crearea de animație a tranziției între Activitate cu un efect „fără întreruperi”.


    Din punct de vedere vizual, animațiile de tranziție între Activități prezentate în cadrul Transitions Framework pot fi împărțite în două tipuri: animații obișnuite și animații cu un element comun. Conceptul de animație cu un element comun este demonstrat într-o figură furată sincer de pe developer.android.com. 1. Elementele comune de pe acesta sunt avatarul și numele persoanei de contact.


    Orez. 1. Animație de tranziție între Activitate cu elemente comune

    Dar nimănui nu-i plac prezentările lungi, așa că să trecem direct la povestea modului în care au fost create animațiile de acest tipîn aplicația iFunny. Ca prim exemplu, luați în considerare animația prezentată în Fig. 2. Pentru a-l folosi avem nevoie versiuni Android 5.0 și mai mare.


    Orez. 2. Animație a tranziției între Activitate pe ecranul de autentificare a utilizatorului

    Din punctul de vedere al utilizatorului, nu este nimic neobișnuit aici: un ecran, animație simplă. Dar, după cum probabil ați ghicit, „sub capotă” este tranziția între două ecrane cu un element comun.

    Primul pas pentru a crea o astfel de tranziție este, în mod ciudat, selectarea acestui element și determinarea locației acestuia în aspectul ambelor Activități. După aceasta, trebuie să adăugați atributul android:transitionName la descrierea fiecărei vizualizări care afișează elementul selectat și, de asemenea, să le atribuiți un android:id dacă lipsește.

    În cazul nostru, acestea sunt ImageViews obișnuite de următoarea formă:


    Există două lucruri care merită remarcate aici Puncte importante. În primul rând, ambele ImageViews trebuie setate la același transitionName, ceea ce este logic. În al doilea rând, din moment ce folosim ImageView, conținutul lor trebuie să fie același, deoarece utilizarea a două resurse diferite poate duce la consecințe neașteptate (cel puțin la clipirea vizualizării animate la începutul și la sfârșitul animației).

    În al doilea pas, trebuie să adăugați opțiuni pentru (a doua) Activitate lansată, indicând faptul că o animație ar trebui să fie lansată când începe.

    Notă. Prin „a doua” înțelegem Activitatea lansată, a cărei tranziție trebuie efectuată, iar prin „întâi” înțelegem Activitatea de lansare.

    Acest lucru se face după cum urmează:

    Bundle bundle = nul; if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) ( Vizualizare v = activity.findViewById(R.id.auth_logo); if (v != null) ( Opțiuni ActivityOptions = ActivityOptions.makeSceneTransitionAnimation(activitate) , v, activity.getString(R.string.email_auth_transition)); if (pachet == null) ( activity.startActivity(intent); ) else ( activity.startActivity(intent, bundle); )
    In urmatoarea lista:

    • R.id.auth_logo - ImageView din prima Activitate, folosită în animație;
    • activitate - prima Activitate;
    • R.string.email_auth_transition - o etichetă lăsată anterior în aspectul ambelor ImageViews;
    • SecondActivity.class - a doua Activitate.
    Și acum cititorul atent poate fi perplex: în introducere am vorbit despre utilizarea nivelului API 19, în exemplu era nivelul API 21, iar în lista de mai sus există o restricție la nivelul API 22. Din păcate, atunci când scrieți codul s-a dovedit că animațiile de tranziție cu un element comun se pot comporta incorect pe telefoanele cu nivelul API 21. Acest lucru se manifestă sub formă de încetiniri ale animației în general și artefacte pe vizualizarea animată în special. Dacă sunteți deja familiarizat cu subiectul, cunoașteți motivele acestui comportament și/sau modalități de a rezolva problema descrisă, spuneți-ne în comentarii.

    La al treilea pas, este necesar să descriem animația de tranziție, adică. indica calea parcursă de Vederea animată și transformarea Vederii în sine. Pentru a face acest lucru, creați un fișier separat projectName/src/main/res/transitions/email_auth_transition.xml cu următorul conținut:


    Puțină teorie. Eticheta transitionSet este destinată să descrie mai multe transformări aplicate vizualizării animate simultan. Parametrul transitionOrdering controlează ordinea în care sunt aplicate aceste transformări. În cazul nostru, acestea sunt aplicate simultan. Există mai multe tipuri de transformări pre-construite furnizate în cadrul de tranziții. CU lista plina poate fi găsit pe această pagină. Ne vom concentra pe două specifice: changeBounds și changeImageTransform.

    Prima este pentru transformarea dimensiunii Vizualizării. Al doilea funcționează numai cu ImageView și, împreună cu primul, vă permite să schimbați nu numai dimensiunea, ci și forma ImageView-ului. Folosind datele de transformare, obținem animația de ieșire a modificării dimensiunii imaginii, prezentată în Fig. 2. Dacă nu specificați tipul de mișcare a vizualizării animate, atunci aceasta se va deplasa cel mai scurt traseu. Mai mult mod interesant Vom lua în considerare mișcarea în al doilea exemplu.

    Ultimul pas în crearea unei animații este declararea acesteia în temele ambelor Activități. Pentru a face acest lucru, editați descrierea temelor după cum urmează (sau creați altele noi în folderul projectName/src/main/res/values-v22/theme.xml):


    Aici:

    • android:windowActivityTransitions permite animațiile de tranziție;
    • android:windowSharedElementEnterTransition indică un fișier care descrie animația tranziției de la prima activitate la a doua;
    • android:windowSharedElementExitTransition indică un fișier care descrie animația de tranziție la întoarcerea de la a doua activitate la prima.
    Trebuie remarcat faptul că pentru versiunile OS sub 5.1 este necesar să se creeze teme cu stiluri identice pentru a evita consecințele destul de așteptate ale prăbușirii aplicației. De exemplu, să le punem în fișierul projectName/src/main/res/values/theme.xml: