O scufundare profundă în pachetul Flutter Animations

O prezentare generală a noului sistem de mișcare Design material Google, plus exemple ale noului pachet de animații Flutter.

La 21 februarie 2020, echipa Flutter a lansat pachetul de animații ca parte a noului sistem de mișcare Design material Google. Acest pachet le permite dezvoltatorilor Flutter să implementeze animații și modele de tranziție utilizate în aplicațiile lor mult mai ușor decât înainte. În această postare, vom trece în revistă sistemul de mișcare și vom arăta cum să folosim pachetul de animații pentru a crea acele noi tranziții în Flutter. De asemenea, vedem cum se încadrează în uzurile existente ale widgeturilor Navigator și Hero.

O prezentare generală a sistemului de mișcare de proiectare a materialelor

Material Design este un sistem de design agnostic de platformă de la Google, care vine cu implementări native iOS, Android, web și Flutter. Sistemul de mișcare este un nou adaos la Material Design și constă din patru modele de tranziție care îi ajută pe utilizatori să înțeleagă și să navigheze printr-o aplicație:

Transformare container

Aproape fiecare aplicație folosește modelul de detaliu principal, cum ar fi navigarea dintr-o vizualizare listă într-o vizualizare detaliu. Aici se potrivește transformarea containerului. Transformând fără probleme o țiglă listă într-o pagină de detalii, relația dintre cele două componente este menținută. Atâta timp cât există o zonă închisă care acționează ca un element persistent în tranziție, este un bun candidat pentru transformarea containerului. Alte exemple sunt tranziția unei bare de căutare într-o pagină de căutare extinsă cu mai multe opțiuni și filtre și un cip într-un cip extins. Transformarea containerului nu trebuie să fie strict pe ecran complet; se poate aplica și în scenarii în care o componentă mai mică se extinde într-una mai mare.

Axa partajată

Modelul Axa partajată poate fi utilizat dacă elementele dintr-o tranziție nu au un container persistent, dar partajează totuși un aspect comun de navigație sau orizontală / verticală. Un bun exemplu este navigarea înainte și înapoi într-un flux tipic de integrare. În acest caz, modelul Shared Axis adaugă o traducere orizontală plus o fade-in și fade-out la fiecare tranziție de pagină. Traducerea nu se limitează la axa x; poate fi aplicat și pe axa y (verticală) sau pe axa z (adâncime).

Fade through

Modelul Fade through se aplică scenariilor în care componentele UI nu au neapărat o relație spațială sau de navigație puternică între ele. Acest model înlocuiește conținutul pe loc cu o combinație de fade și tranziție la scară. Acest lucru este util atunci când există o modificare substanțială a conținutului afișat. De exemplu, când atingeți un buton de reîmprospătare pentru a reîncărca date pe un ecran. Când se actualizează interfața de utilizare, efectul de estompare și scară oferă utilizatorului impresia că datele au fost modificate substanțial.

< Decolorare

Tranziția Fade se aplică scenariilor în care un element UI pur și simplu intră sau iese din ecran, spre deosebire de tranziția Fade through, unde elementele UI par să se actualizeze în loc. Acest lucru se realizează, de asemenea, folosind o animație de estompare și scară, dar poate fi, de asemenea, repoziționat pentru a părea să iasă dintr-o anumită parte a ecranului. În mod implicit, tranziția variază de la centru. Un bun caz de utilizare pentru această tranziție este prezentarea unui dialog sau a unui meniu derulant care ar fi discordant dacă ar apărea imediat.

Pachetul de animații Flutter

În calitate de cetățean de primă clasă în proiectarea materialelor, suntem încântați că Flutter a primit sprijin pentru noul sistem de mișcare în prima zi prin pachetul de animații! Acesta este un pachet de primă parte de la echipa Flutter și este disponibil pe pub.dev. Să ne scufundăm într-un anumit cod și să aflăm cum să-l folosim.

Transformarea containerului

Noua transformare Material Design Container este implementată în Flutter utilizând widget-ul OpenContainer. Trece între două widget-uri copil fără probleme, astfel încât acestea să pară aceleași widget. Copiii sunt furnizați prin proprietățile closedBuilder și openBuilder . Aceste funcții de generare oferă un BuildContext standard, precum și o apelare suplimentară acțiune , care este utilizată pentru a declanșa animația pentru a deschide și închide widgetul. Există, de asemenea, un parametru tappable (care implicit este true ) care poate declanșa tranziția „deschisă” la atingere ca alternativă la apelarea action . Rețineți că nu declanșează și animația „închisă”.

Putem specifica culoarea, înălțimea și forma stărilor închise și deschise, iar Flutter va interpola fără probleme între ele. Puteți modifica durata de tranziție, precum și tipul de tranziție. Valoarea ContainerTransitionType.fade suprapune widgeturile dintr-o decolorare încrucișată; valoarea ContainerTransitionType.fadeTrough modifică decolorarea widgetului, astfel încât să nu se suprapună.

Este important să rețineți că widget-ul OpenContainer trebuie utilizat într-un context cu un Navigator. Când trece de la widget-ul închis la widget-ul deschis, împinge un nou PageRoute pe cel mai apropiat strămoș Navigator. Apoi crește widgetul deschis pentru a umple întreaga dimensiune a acestui navigator. Majoritatea navigatorilor sunt cu ecran complet, dar nu trebuie să fie. Iată un exemplu care generează GIF de mai sus:

Axa partajată

Noua tranziție axă partajată Material Design este implementată în Flutter utilizând widgetul SharedAxisTransition. Acesta generează o tranziție partajată + tranziție de decolorare, fie în axa x, y sau z. Acceptă ca parametru un widget copil . Animația dintre widget-urile copil „vechi” și „noi” este controlată de parametrii animație și secundarăAnimație . Aceasta înseamnă că widgetul SharedAxisTransition nu poate trăi singur și trebuie să fie „condus” de o sursă externă. O astfel de sursă este noul widget PageTransitionSwitcher, care face parte din pachetul de animații și este utilizat pentru a alinia tranzițiile între widget-uri. Acest widget este similar cu widgetul AnimatedSwitcher, care face o decolorare încrucișată între copilul „vechi” și „nou”, dar ne permite să definim animațiile de intrare și ieșire separat.

Pentru a utiliza în mod implicit tranziția SharedAxisTransition pentru toate rutele din interiorul unui Navigator, puteți adăuga un PageTransitionsTheme la ThemeData de MaterialApp. Adăugați un SharedAxisPageTransitionsBuilder la proprietatea builders cu tipul de tranziție dorit pentru fiecare platformă unde doriți să se aplice această tranziție:

Aveți grijă, totuși – această tehnică este o abordare totală sau nulă și funcționează numai pentru rutele denumite . Dar dacă vrem să împingem rutele programatic către un Navigator, ca în exemplul următor?

Această tehnică ne ajută să decuplăm mai bine conținutul nostru ( MyWidget ) de tranziția noastră (MaterialPageRoute). Pentru a utiliza tranziția SharedAxisTransition, putem crea doar un PageRoute nou care îl consumă. Putem subclasa PageRoute sau putem folosi un PageRouteBuilder:

Apoi, putem continua să împingem noi ecrane pe Navigator prin program:

Fade through

Noul Material Design Fade through transition este implementat în Flutter utilizând widgetul FadeThroughTransition. Acest widget aplică o tranziție de decolorare la elementul de ieșire și o tranziție de decolorare și scară la elementul de intrare. Similar cu SharedAxisTransition, poate fi utilizat și în interiorul unui widget PageTransitionSwitcher, aplicat global tuturor rutelor Navigator denumite sau aplicat selectiv numai anumitor rute printr-un PageRoute personalizat.

Fade

Noua tranziție Material Design Fade este implementată în Flutter utilizând widgetul FadeScaleTransition. Elementele care intră se estompează cu opacitate și scară crescândă de la 80% la 100%, în timp ce elementele care ies se estompează cu opacitate scăzută. Poate fi folosit și în interiorul unui widget PageTransitionSwitcher, aplicat global la toate rutele Navigator denumite, aplicat selectiv folosind un PageRoute personalizat sau afișat folosind noua metodă showModal ():

showModal ()

Pachetul de animații Flutter introduce o nouă funcție globală numită showModal () care poate fi utilizată pentru a afișa conținut într-un mod în Navigatorul curent. Acest lucru este foarte similar cu funcția existentă showGeneralDialog () care face parte din material.dart. Diferența constă în faptul că proprietățile de configurare modală au fost extrase într-un singur argument de configurare de tip ModalConfiguration. Această clasă conține diverse caracteristici ale modului, cum ar fi tranzițiile de intrare și ieșire, durata tranzițiilor și proprietățile barierei modale. În plus, există o subclasă numită FadeScaleTransitionConfiguration care aplică valorile standard din noua tranziție Material Design Fade. Iată un exemplu de utilizare a acestuia împreună cu metoda showModal ():

O notă despre widgeturile Hero

Widgetul Hero poate fi folosit pentru a crea un efect vizual plăcut atunci când faceți tranziția între rute într-un Navigator. Un widget Hero apare de la locația sa originală în vechea rută până la locația sa finală în noua rută. Cu toate acestea, în testarea noastră, widgeturile Hero nu funcționează cu noile tranziții Material Design atunci când sunt utilizate într-un OpenContainer sau un PageTransitionSwitcher. Cu toate acestea, funcționează funcționează atunci când se utilizează tehnica de subclasare PageRoute prezentată mai sus.

Concluzie

Noul sistem de mișcare este o evoluție interesantă a designului materialului și reflectă importanța crescândă a efectelor de mișcare în proiectarea modernă a aplicațiilor. Noile tranziții sunt subtile și comunicative, fără a fi preponderente. Este fantastic că au suport de primă clasă în Flutter prin pachetul de animații. Suntem deosebit de încântați că pot fi folosite și ca implementări personalizate PageRoute. Vă încurajăm să încercați!

Renunțare: observațiile de mai sus sunt rezultatul testării rapide a noului pachet de animații Flutter. Spuneți-ne în comentarii dacă găsiți ceva diferit în propriile testări.

Kawynfurstoss și Hashim Hayat au contribuit la această postare pe blog.