Studiem proprietăți utile și creăm animații pe Android. Adăugarea de animații bazate pe fizică la aplicațiile Android
Ziua bună tuturor. Vreau să dedic această postare subiectului fragmentelor pentru Android. Există deja traduceri și câteva articole despre Habré care menționează cum să începeți să lucrați cu fragmente pentru Android. De exemplu, articol. Conține o descriere a ce sunt fragmentele și în ce versiuni Android sunt disponibile, așa că cei care nu au ajuns încă la el se pot familiariza cu el dacă doresc, dar nu voi re povesti acest lucru în postarea mea. Așa că voi ajunge direct la subiect.
Începutul lucrării
Permiteți-mi să spun pe scurt că fragmentele sunt componente ale utilizatorului UI care pot fi utilizate folosind clasa Activitate pentru a afișa datele utilizatorului, dar ciclul lor de viață nu depinde de aceasta. Funcționalitatea oferită de fragmente are o funcționalitate mai largă pentru lucrul cu ele decât Activity, așa că utilizarea lor este de o importanță nu mică pentru dezvoltatori dacă doresc ca aplicația lor să aibă o interfață de utilizator mai modernă în raport cu standardele actuale.Acum să trecem la subiectul postării. Dezvoltatori Google fragmentele au fost înzestrate, în opinia mea, cu un suport excelent pentru animația de afișare a fragmentului în sine. Acest lucru va fi discutat în continuare. Am căutat pe Habr postări pe Acest subiect, dar nu am găsit nimic, așa că acum îmi voi împărtăși cunoștințele.
Crearea unui proiect
Să creăm un mic proiect. Am creat un proiect pentru Samsung Nexus S al meu, unde am versiunea Android 4.1.2, care este ceea ce am folosit (Api Level 16). Am numit proiectul însuși FragmentsAnimationTest.Pentru demonstrație, vom avea nevoie de activitatea principală și aspectul acesteia, câteva fragmente, fiecare cu aspectul său, și încă câteva fișiere xml pentru animația în sine, despre care voi vorbi mai târziu.
Aplicația va arăta astfel: unul dintre fragmente va fi afișat pe ecran, comutarea între ele se va face folosind un buton obișnuit și, în consecință, comutarea fragmentelor în sine va fi însoțită de efecte de animație.
Mai întâi, să aranjam elementele activității principale în fișierul activity_main.xml:
Din cod reiese clar că se utilizează aspectul principal - RelativeLayout, care este destul de convenabil atunci când lucrați cu fragmente; poate găzdui două element standard FrameLayout - de fapt, va fi un container pentru fragmente și un buton care va fi folosit pentru a comuta fragmentele între ele. Deocamdată, totul ar trebui să fie extrem de simplu.
În continuare, să trecem la fragmentele noastre. Să creăm un marcaj pentru ei și pentru clasele în sine:
fragment1.xml
Fragment2.xml
Pentru ambele fragmente, codul este aproape același, singura diferență este textul care va fi afișat în fragmentul în sine pentru a-l identifica și culoarea de fundal, astfel încât animația să fie clar vizibilă.
Fragment1.java
clasa publică Fragment1 extinde Fragment ( @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) ( return inflater.inflate(R.layout.fragment_1, null); ) )
Fragment2.java
clasa publică Fragment2 extinde Fragment( @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) ( return inflater.inflate(R.layout.fragment_2, null); ) )
La cursuri, totul ar trebui să fie clar și dacă ești familiarizat cu subiectul fragmentelor. Ele indică pur și simplu ce excludere exactă va fi folosită atunci când se afișează un anumit fragment și asta este tot.
Acum să trecem la partea delicioasă. Să lucrăm cu clasa de activitate principală, iată codul acesteia:
clasa publică MainActivity extinde Activitatea ( fragment privat Fragment2; fragment privat Fragment1; privat FragmentTransaction ft; @Override protejat void onCreate(Bundle savedInstanceState) ( super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); fragment1 = nou Fragment1() ; fragment2 = nou Fragment2(); ft = getFragmentManager().beginTransaction(); ft.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_in_right); // ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN(); ft. R.id.fragCont, fragment1); ft.addToBackStack(null); ft.commit(); Button btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() ( @Override public void onClick(View v) ( ft = getFragmentManager().beginTransaction(); ft.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_in_right); // ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); if(fragment(1.is) ))( ft.replace(R.id.fragCont, fragment2); )else( ft.replace(R.id.fragCont, fragment1); ) ft.commit(); ) )); ) )
Să ne uităm la ce se întâmplă exact în activitatea noastră. În primul rând, sunt create ambele fragmente, care, după cum sa menționat deja, se vor schimba alternativ reciproc. În continuare, indicăm cu linia ft = getFragmentManager().beginTransaction() obținem o FragmentTransaction, cu care putem interacționa cu fragmentele noastre, dar totul este în articolul pe care l-am menționat mai devreme. Înainte de a trece la analiza următorului cod, voi face o mică digresiune.
Există două opțiuni pentru a crea animații pentru afișarea fragmentelor:
- Prima metodă este să conectați animația standard folosind metoda setTransition(int transit). Clasa FragmentTransaction are mai multe animații predefinite.
- Metoda a 2-a este exact ceea ce ne interesează în acest subiect, implementarea animației personalizate. Efectuat folosind metoda setCustomAnimations().
Câteva comentarii stoc sunt astfel încât să puteți încerca să vă jucați cu animația predescrisă, pur și simplu anulați comentariile și comentați linia anterioară - ft.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_in_right), în ambele cazuri, deși acest lucru nu este necesar.
Să analizăm codul de activitate până la sfârșit și să trecem la crearea animației în sine.
După setarea animației, fragmentul este afișat, adăugat la stivă și tranzacția este finalizată pentru a afișa toate modificările. Apoi ne inițializam butonul și îi atașăm un ascultător de eveniment clic pe butonul, în interiorul căruia există cod pentru schimbarea fragmentelor. Când butonul este apăsat, începem o tranzacție, conectăm animația și schimbăm fragmentul în cel opus afișat în în prezent. Codul este simplu, deci nu necesită o explicație profundă.
Crearea de animație
Să trecem la partea principală a subiectului nostru. Să învățăm cum să creăm animația în sine. Modul în care creăm animația aici este puțin diferit de modul în care suntem obișnuiți să o facem versiuni anterioare Android. Implementarea decurge după cum urmează. Mai întâi trebuie să creați un folder animator în folderul de resurse ale aplicației, acesta va arăta astfel - res/animator/. Aici trebuie să punem fișiere xml care vor descrie exact cum ar trebui să fie redată animația. Să le punem acolo:slide_in_left.xml
Și slide_in_right.xml
Acum să le privim în detaliu. Elementele efectelor vizuale în sine sunt descrise în tag-ul objectAnimator; fiecare astfel de etichetă descrie descrierea unui nou efect de animație. Acum să ne uităm la atributele în sine. Primul atribut din fișierul slide_in_left.xml este interpolator, are mai multe valori, puteți afla mai multe despre ele în documentația Property Animation. Interpolatorul este responsabil pentru afișarea fragmentului nostru într-un anumit mod pentru un anumit timp. În continuare avem atributul propertyName, acesta indică ce proprietate a fragmentului vom schimba în timpul animației; în exemplul nostru, y este primul, iar valueType indică ce tip de parametru schimbăm. ÎN carte Pro Android 4 justifică această situație prin faptul că dacă te uiți la metoda setX() din clasa View, devine clar că ia o valoare de tip float, același lucru este valabil și cu metoda setY(), de unde și valoarea floatType.
Urmează atributele nu lipsite de importanță valueFrom și valueTo, ele indică de la ce valoare să se schimbe valoarea specificată în propertyName, în primul nostru caz este y. Dacă parametrul valueFrom nu este specificat, atunci valoarea este luată egală cu cea curentă. În cazul nostru, valueFrom este egală cu -1280, aceasta înseamnă că mișcarea fragmentului de-a lungul axei y va începe de la valoarea -1280, această valoare a fost aleasă datorită faptului că este situată în afara ecranului dispozitivului și mișcarea. va apărea până când valoarea y devine egală cu 0 pentru colțul din stânga sus al fragmentului nostru timp de 1500 de milisecunde. Și, în sfârșit, atributul duration specifică exact cât timp va dura efectul nostru animat în milisecunde.
Și ultima nuanță pe care vreau să o descriu. Privind la oricare dintre fișierele de descriere a animației, puteți vedea eticheta set, care conține toate efectele de animație; servește pentru a combina efectele sau a le separa. Fișierul slide_in_right.xml folosește atributul de ordonare din eticheta set, în cazul nostru are valoarea împreună, ceea ce înseamnă redarea efectelor simultan, spre deosebire de aceasta există valoarea secvenţial, ceea ce necesită ca efectele să fie afișate secvenţial în animație, ceea ce este foarte convenabil în unele cazuri.
Asta e tot. Fișierul slide_in_right.xml oferă un exemplu despre cum puteți utiliza alte proprietăți pentru animație, cum ar fi canalul alfa. Sper că acest articol va fi util celor cărora le pasă cum va arăta aplicația lor.
După cum înțelegeți, dragi Habrausers, capturile de ecran nu vor putea afișa rezultatul lucrării.
Literatura și sursele care au fost folosite la scrierea postării au fost menționate în cadrul articolului în sine.
Animațiile care par fluide și realiste tind să facă interfețele cu utilizatorul mai atractive. Nu e de mirare că Material Design le acordă atât de multă atenție!
Cu toate acestea, dacă ați încercat vreodată să creați astfel de animații, știți că animatorii și interpolatorii simpli oferiti Android SDK, adesea nu sunt suficient de bune. Acesta este motivul pentru care versiunile recente ale Bibliotecii de asistență Android vin cu modulul de fizică Dynamic Animation.
Cu Animația dinamică, puteți crea animații bazate pe fizică care seamănă foarte mult cu mișcările obiectelor din lumea reala. De asemenea, îi puteți face să reacționeze la acțiunile utilizatorului în timp real. În acest tutorial vă voi arăta cum să creați mai multe dintre aceste animații.
Conditiile necesare
Pentru a urma tutorialul, asigurați-vă că aveți următoarele:
- Android Studio 3.0 Canary 4 sau o versiune ulterioară
- Dispozitiv sau emulator sub Control Android 4.4 sau mai târziu
1. Adăugarea de dependențe
Pentru a putea folosi Animația dinamică în proiect, trebuie să o adăugați ca dependență de implementare în fișier construi.gradle a modulului aplicației dvs.:
Implementarea „com.android.support:support-dynamic-animation:26.0.0-beta2”
În acest tutorial vom anima widget-ul ImageView. Desigur, trebuie să afișeze câteva imagini, așa că deschideți Vector Assets Studio și adăugați următoarele pictograme Material la proiectul dvs.:
- stare de spirit neutră
- starea de spirit este foarte mulțumită
Iată cum arată ele:
Pentru obtinerea cele mai bune rezultate Vă sugerez să setați dimensiunea pictogramelor 56 x 56 dp.
2. Crearea unei animații Fling
Când arunci un obiect în lumea reală, îi dai mult impuls (impuls). Deoarece impulsul nu este altceva decât produsul dintre masă și viteză, obiectul va avea inițial de mare viteză. Treptat însă, datorită frecării, încetinește până se oprește complet din mișcare. Folosind clasa FlingAnimation din Dynamic Animation, puteți simula acest comportament în aplicația dvs.
Pentru a demonstra, acum să creăm un aspect care să conțină un widget pop-up ImageView care afișează o pictogramă și un widget Button pe care utilizatorii pot face clic pentru a declanșa o animație de lansare. Dacă le plasați într-un widget RelativeLayout, fișierul XML de aspect va arăta astfel:
În codul de mai sus, veți vedea că widgetul Button are un atribut onClick. Făcând clic pe pictograma cu un indicator roșu, care Android Studio se va afișa alături de aceasta, puteți apela gestionarea evenimentelor de clic în cadrul clasei dvs. de activitate:
Public void flingIt (Vizualizare vizualizare) ( // mai multe coduri aici )
Acum puteți crea o nouă instanță a clasei FlingAnimation folosind constructorul acesteia, care așteaptă un obiect View și un nume de proprietate de animație. Animația dinamică acceptă mai multe proprietăți de animație, cum ar fi scară, translație, rotație și alfa.
Următorul cod arată cum să creați o instanță FlingAnimation care poate anima coordonatele X a ImageView-ului nostru:
// Obține o referință la vizualizarea ImageView emoji = (ImageView)findViewById(R.id.emoji); // Transmite-l constructorului FlingAnimation flingAnimation = new FlingAnimation(emoji, DynamicAnimation.X);
În mod implicit, o instanță FlingAnimation este configurată să folosească 0 pixeli pe secundă ca viteză inițială. Aceasta înseamnă că animația se va opri imediat ce începe. Pentru a simula pornirea realistă a mișcării, ar trebui să vă amintiți întotdeauna să apelați metoda setStartVelocity() și să îi transmiteți o valoare mare.
De asemenea, trebuie să înțelegeți că, fără frecare, animația nu se va opri. Deci, ar trebui să apelați și metoda setFriction() și să îi transmiteți un număr mic.
Următorul cod configurează instanța FlingAnimation astfel încât ImageView să nu se extindă dincolo de ecranul utilizatorului:
FlingAnimation.setStartVelocity(500f); flingAnimation.setFriction(0.5f);
În acest moment, puteți apela pur și simplu metoda start() pentru a porni animația.
FlingAnimation.start();
Dacă lansați aplicația acum și apăsați butonul, veți putea vedea animația fling.
Este de remarcat faptul că nu specificați o durată sau o valoare finală atunci când creați o animație bazată pe fizică - animația se oprește automat atunci când își dă seama că obiectul său țintă nu arată nicio mișcare vizibilă pe ecranul utilizatorului.
3. Imitația unui izvor - Izvoare
Animația dinamică facilitează adăugarea mișcării de primăvară la animația dvs. Cu alte cuvinte, vă poate ajuta să creați animații care să facă widget-urile să sară, să se întindă și să se zdrobească în moduri care să pară naturale.
Pentru a menține lucrurile simple, acum să reutilizam ImageView a aspectului nostru și să îi aplicăm o animație de primăvară. Cu toate acestea, pentru a permite utilizatorului să declanșeze animația, trebuie să adăugați un alt widget Button la aspectul dvs.
Pentru a crea o animație bazată pe primăvară, trebuie să utilizați clasa SpringAnimation. Constructorul său așteaptă, de asemenea, un obiect View și o proprietate de animație. Următorul cod creează o instanță SpringAnimation configurată pentru a anima coordonatele X a ImageView-ului:
// Obține o referință la vizualizarea finală ImageView emoji = (ImageView)findViewById(R.id.emoji); // Transmite-l constructorului SpringAnimation springAnimation = new SpringAnimation(emoji, DynamicAnimation.X);
Pentru a controla comportamentul animației bazate pe primăvară, veți avea nevoie de primăvară. Puteți crea unul folosind clasa SpringForce, care vă permite să specificați poziția de repaus pentru balansare, factorul de amortizare și rigiditatea. Vă puteți gândi la factorul de amortizare ca la o constantă care, la fel ca frecarea, este responsabilă pentru încetinirea animației până când se oprește. Pe de altă parte, rigiditatea determină cât de multă forță este necesară pentru a întinde un arc.
Dacă toate acestea sună prea complicat, vestea bună este că clasa SpringForce oferă mai multe constante denumite în mod obișnuit pe care le puteți utiliza pentru a configura rapid arcul. De exemplu, următorul cod creează un arc care este atât foarte elastic, cât și foarte flexibil:
SpringForce springForce = nou SpringForce(); springForce.setFinalPosition(emoji.getX()); springForce.setDampingRatio(SpringForce.DAMPING_RATIO_HIGH_BOUNCY); springForce.setStiffness(SpringForce.STIFFNESS_LOW);
În codul de mai sus, puteți vedea că am setat valoarea poziției de repaus final a arcului la coordonata X de început a ImageView. Cu această configurație, vă puteți imagina că ImageView este legat de o bandă de cauciuc rigidă, invizibilă, care trage rapid ImageView înapoi în poziția inițială de fiecare dată când este mutat.
Acum puteți asocia un resort cu o instanță SpringAnimation folosind metoda setSpring().
SpringAnimation.setSpring(springForce);
În cele din urmă, înainte de a începe animația, ar trebui să vă asigurați că îi oferiți o viteză mare de pornire folosind metoda setStartVelocity().
SpringAnimation.setStartVelocity(2000f); springAnimation.start();
Dacă rulați aplicația acum, veți vedea ceva de genul acesta:
4. Ascultarea evenimentelor de animație
Animațiile create folosind biblioteca de animații dinamice ar trebui să fie lansate întotdeauna din interfața cu utilizatorul. De asemenea, puteți fi sigur că va porni imediat ce apelați metoda start(). Cu toate acestea, rulează asincron. Deci, dacă doriți să fiți notificat când se termină, trebuie să atașați un obiect OnAnimationEndListener utilizând metoda addEndListener().
Pentru a vedea ascultătorul în acțiune, să schimbăm pictograma Material pentru începutul și sfârșitul animației afișate de ImageView de fiecare dată când animația de primăvară am creat-o în pasul anterior. Vă sugerez să utilizați pictograma ic_sentiment_very_satisfied_black_56dp la pornirea animației și pictogramei ic_sentiment_neutral_black_56dp la sfârșitul. Următorul cod arată cum:
// Schimbați pictograma înainte de a începe animația emoji.setImageResource(R.drawable.ic_sentiment_very_satisfied_black_56dp); // Începe animația springAnimation.start(); springAnimation.addEndListener(new DynamicAnimation.OnAnimationEndListener() ( @Override public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value, float speed) ( // Schimbați pictograma după ce animația se termină emoji.setImageResource(R.drawable_5outic_p) ; );
Cu codul de mai sus, animația ar arăta astfel:
5. Animați proprietăți multiple
Constructorii claselor FlingAnimation și SpringAnimation pot accepta doar o proprietate de animație. Dacă doriți să animați mai multe proprietăți simultan, puteți crea mai multe instanțe de clase, care pot deveni greu de manevrat, sau puteți crea o nouă proprietate personalizată care surprinde în mod succint toate proprietățile dorite.
Pentru a crea o proprietate de animație personalizată, trebuie să subclasați clasa FloatPropertyCompat, care are două metode abstracte: setValue() și getValue() . După cum probabil ați ghicit, puteți actualiza valorile tuturor proprietăților de animație pe care le doriți în cadrul metodei setValue(). Cu toate acestea, metoda getValue() trebuie doar să returneze valoarea curentă a oricărei proprietăți. Din cauza acestei limitări, de obicei trebuie să vă asigurați că valorile proprietăților scurtate nu sunt complet independente unele de altele.
De exemplu, următorul cod vă arată cum să creați o proprietate personalizată numită scale, care poate anima proprietățile SCALE_X și SCALE_Y ale widget-ului în mod uniform:
FloatPropertyCompat
Acum că proprietatea noastră este gata, o puteți folosi ca orice altă proprietate de animație. Următorul cod arată cum să creați un obiect SpringAnimation cu acesta:
SpringAnimation stretchAnimation = nou SpringAnimation (emoji, scară);
Când creați o animație care utilizează o proprietate personalizată, este, de asemenea, o idee bună să apelați metoda setMinimumVisibleChange() și să îi transmiteți o valoare semnificativă pentru a vă asigura că animația nu consumă prea mult CPU. Pentru animația noastră care scalează widget-ul, puteți folosi următorul cod:
StretchAnimation.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE);
Iată cum arată o animație de proprietate personalizată:
Concluzie
Acum cunoașteți elementele de bază ale lucrului cu Animația dinamică. Folosind tehnicile pe care le-ați învățat în acest tutorial, puteți crea animații convingătoare bazate pe fizică în câteva minute, chiar dacă aveți puține cunoștințe despre fizica newtoniană.
Pentru a afla mai multe despre animația dinamică, consultați documentația oficială. Între timp, consultați câteva dintre celelalte articole recente despre dezvoltarea aplicației Android!
La ribot, ne pasă să creăm experiențe frumoase și semnificative pentru oameni, î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 descoperirile 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
Securitate părere, atunci când utilizatorul atinge ecranul, ajută la comunicarea într-o manieră vizuală, astfel încât să aibă loc interacțiunea. Aceste animații nu ar trebui să distragă atenția utilizatorului, ci 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 animația începe, se termină, se repetă sau este anulată.
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ție de animație) ( )
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 compatibilitate cu versiunea anterioară, puteți utiliza 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 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 cu care începe vizualizarea animației.
Culoare țintă - Culoarea cu care această imagine ar trebui 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
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 utilizat 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ă
- Skipping Interpolator - Imaginea „revitalizează” exagerarea valoare dată, revenind la valoarea cerută
Animație circulară
Animația CircularReveal folosește un cerc decupat fie pentru a dezvălui, fie pentru a ascunde un grup de elemente UI. 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.
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 glisare 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 cu diapozitive vă permite să alunecați secvențial în imaginile 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: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:
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:
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:
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 tipuri care au fost incluse în tranzițiile noastre:
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:transitionName="@string/transition_view“/>
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 optiuni aproximative tranzacții, de exemplu (ActivityOptionsCompat), astfel încât ambele activități să fie conștiente componente 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 ne crea cele două separate fișiere vectoriale fiecare dintre ele are mai multe 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 & Y - Declarați pivotul utilizat pentru scara grupului și rotație
- Calea culorii de umplere - Culoarea de umplere a căii vectoriale
- 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: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:width="56dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0“>
android:pivotX="12"
android:pivotY="12“>
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 utilizate 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:animation="@animator/add_to_remove“ />
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
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:
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ățească felul în care arată și se simt modelele 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 acest lucru și despre unde folosiți aceste animații - vă rugăm să lăsați o recenzie sau să mă scrieți pe Twitter!
În acest articol ne vom uita la 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
xml
version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
<
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
"
/>
set
>
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 dintr-un fișier xml, utilizați metoda statică a clasei 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:
clasa 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); button = (Button )findViewById(R.id.button); anim = AnimationUtils.loadAnimation(this , R.anim.anim); // 1 button.setOnClickListener(new OnClickListener() ( @Override public void 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 matematica computațională, o metodă de găsire a valorilor intermediare ale unei mărimi dintr-un set discret de valori existent. 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 a punctului final al mișcării
- 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:
xml
version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
<
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
"
/>
set
>
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(modul de repetare) - aceste atribute vor fi aplicate fiecărei animații din set
- interpolator- defineşte interpolatorul de animaţie şi shareInterpolator- dacă acest interpolator va fi aplicat pentru fiecare animație din set (valorile posibile sunt „adevărat” și „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ă a utiliza 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); //3 rotate.setRepeatMode(Animation.REVERSE); //4 rotate.setRepeatCount(1); //5 durată lungă = rotate.computeDurationHint(); //6 float size = random.nextFloat() + 1.0; //7 ScaleAnimation scale = new ScaleAnimation(1.0f, dimensiune, 1.0f, dimensiune, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_ , 0,5f); //8 scale.setDuration(1000); scale.setStartOffset(durată); //9 AnimationSet set = nou AnimationSet (fals); //10 set.addAnimation(rotate); //11 set.addAnimation (scale); image.startAnimation(set); //12 ) ));
1) Creați un obiect Random pentru a genera numere aleatorii. Puteți citi mai multe despre Random în documentație; acum suntem interesați de 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) Calculați noua dimensiune a imaginii. 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