Animation i Android: hvordan det virker. Vi studerer nyttige egenskaber og laver animationer på Android
I denne artikel vil vi se på, hvordan man animerer grænsefladeelementer i Android. Under grænsefladeelementerne i I dette tilfælde dette betyder alle efterkommere af View-klassen (en komplet liste over efterkommere kan findes i dokumentationen til View-klassen). Animation er en nem måde at gøre en applikation mere livlig på :)
1.
Lad os starte med at oprette en testside. Lad os lave en simpel applikation med en knap og et billede midt på skærmen. Jeg vil ikke give koden, det er enkelt, hvis noget, se på kilderne (de er i slutningen af artiklen).
2.
I mappen /res/anim skal du oprette en fil anim.xml og skrive der
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
>
Dette er animationsbeskrivelsen, som vi vil anvende på vores billede. Vi vil se på, hvad der sker her mere detaljeret nedenfor, men indtil videre kopierer vi det bare til en fil.
3.
For at indlæse en animation fra xml-fil Brugt statisk metode klasse AnimationUtils
loadAnimation(kontekstkontekst, int id), Hvor sammenhæng er den aktuelle kontekst, og id- id for ressourcen med animation. Metoden returnerer en forekomst af klassen Animation.
Animation - en abstrakt klasse til at repræsentere animation i en applikation.
For at anvende det, overføres den resulterende forekomst af klassen Animation til metoden
startAnimation( Animation animation)
klasse View (og alle dens efterkommere).
4.
Lad os skrive til filen AnimationTestActivity.java:
public class AnimationTestActivity udvider aktivitet ( ImageView-billede; Knap-knap; Animation anim; @Override protected void onCreate(Bundle savedInstanceState) ( super .onCreate(savedInstanceState); setContentView(R.layout.main); image = (ImageView)findViewById(R. id.image); button = (Button )findViewById(R.id.button); anim = AnimationUtils.loadAnimation(this, R.anim.anim); // 1 button.setOnClickListener(ny OnClickListener() ( @Override public void onClick(View v) ( image.startAnimation(anim); //2 ) )); ) )
1) Læs filen med identifikatoren R.anim.anim (som svarer til filen /res/anim/anim.xml) og få en instans af klassen Animation.
2) Ved at klikke på knappen anvender vi animation på billedet.
5. Du kan køre vores applikation. Når du trykker på knappen, forsvinder billedet og begynder derefter langsomt at komme tilbage.
6.
Lad os nu se nærmere på, hvordan animation oprettes i en xml-fil.
Der er 4 typer animation:
- alfa(gennemsigtighed, synlighed)
- vægt(skalering)
- rotere(tur)
- Oversætte(bevæge sig)
For at skabe animation skal vi beskrive objektets begyndelses- og sluttilstand, og systemet vil selv bestemme, hvordan man flytter fra en tilstand til en anden. I vores eksempel
<
alpha
android:fromAlpha="
0.0
"
android:toAlpha="
1.0
"
android:duration="
1000
"
/>
vi beskriver alfa-animationen, det vil sige, at vi ændrer objektets synlighed. Indstil den oprindelige tilstand fromAlpha="0.0"(fuldstændig usynlig) og endelig toAlpha="1.0"(fuldt synlig). Angiv varigheden af animationen duration="1000"(i millisekunder). Og alt andet, det vil sige, hvordan man ændrer synligheden af et objekt for at gøre det fra usynligt til synligt på et sekund, gør systemet selv. Dette beregnes vha interpolation- i beregningsmatematik, en metode til at finde mellemværdier af en mængde fra et eksisterende diskret sæt værdier. For hver animation kan du indstille en interpolator
-AccelerateDecelerateInterpolator(@android:anim/accelerate_decelerate_int erpolator) - ændringshastigheden er lav i begyndelsen og slutningen og accelererer i midten
-Accelerate Interpolator(@android:anim/accelerate_interpolator) - ændringshastigheden starter lavt og accelererer derefter
-Anticipate Interpolator(@android:anim/anticipate_interpolator) - ændringer starter i den modsatte retning og går derefter skarpt fremad
-AnticipateOvershoot Interpolator(@android:anim/anticipate_overshoot_inte rpolator) - ændringer starter i den modsatte retning, flyt derefter hurtigt fremad og flyve over den endelige værdi, og vend derefter tilbage til den endelige værdi
- Bounce Interpolator(@android:anim/bounce_interpolator) - ændringshastigheden stiger i slutningen
- Cycle Interpolator(@android:anim/cycle_interpolator) - gentag animationen et bestemt antal gange. Ændringshastigheden følger en sinusbølge
- Decelerate Interpolator(@android:anim/decelerate_interpolator) - ændringshastigheden falder til sidst
-Lineær interpolator(@android:anim/linear_interpolator) - ændringshastigheden er konstant
-Overshoot Interpolator(@android:anim/overshoot_interpolator) - ændringer springer frem og flyver over den endelige værdi, og vender derefter tilbage til den endelige værdi
Interpolatoren indstilles ved hjælp af android:interpolator-attributten. For eksempel
android:interpolator="@android:anim/cyklus e_interpolator". Standard er LinearInterpolator.
7. Beskrivelse af begyndelses- og sluttilstande
1) alfa (gennemsigtighed, synlighed)
- android:fromAlpha- indledende gennemsigtighedsværdi. 0,0 - fuldstændig gennemsigtig (usynlig), 1,0 - fuldstændig uigennemsigtig (synlig)
- android:toAlpha- endelig gennemsigtighedsværdi
2) vægt
- android:fromXScale- indledende skalaværdi langs X-aksen (hvor den aktuelle størrelse svarer til værdien 1,0)
- android:toXScale- endelig skalaværdi langs X-aksen
- android:fromYScale- indledende skalaværdi langs Y-aksen (hvor den aktuelle størrelse svarer til værdien 1,0)
- android:toYScale- endelig skalaværdi langs Y-aksen
- android:pivotX- x-koordinat for punktet, som forbliver uændret efter skalering
- android:pivotY- y-koordinat for punktet, som forbliver uændret efter skalering
Mulige værdier for pivotX og pivotY:
i pixels i forhold til venstre (eller øverste for Y-koordinat) kant af elementet (f.eks. "5")
som en procentdel i forhold til venstre (øverste) kant (f.eks. "5 %)")
som en procentdel i forhold til venstre (øverste) kant af det overordnede element (f.eks. "5%p")
For eksempel, hvis pivotX=0, pivotY=0 (som svarer til elementets øverste venstre hjørne), så vil skalering ændre størrelsen på elementet ned og til højre. Hvis pivotX=50%, pivotY=50%, så er punktet i midten af elementet, og størrelsen ændres i alle retninger, mens midten forbliver i et punkt.
3) dreje (drej)
- android:fromDegrees- Indledende værdi af rotationsvinklen (i grader, negativ værdi mulig)
- android:toDegrees- endelig værdi af rotationsvinklen
- android:pivotX- x-koordinater for rotationscentrum.
- android:pivotY- y-koordinat for rotationscentrum.
Mulige værdier for pivotX og pivotY som i skalaanimationen
4) oversætte (flytte)
- android:fromXDelta- x-koordinat for bevægelsens startpunkt. Mulige værdier:
i pixels i forhold til den oprindelige position (for eksempel "5")
som en procentdel i forhold til bredden af elementet (f.eks. "5 %)"
som en procentdel i forhold til bredden af det overordnede element (f.eks. "5%p")
- android:toXDelta- x-koordinat for bevægelsens slutpunkt
- android:fromYDelta- y-koordinat for bevægelsens udgangspunkt
- android:toYDelta- y-koordinat for bevægelsens slutpunkt
8. Yderligere muligheder
Der er også attributter, der er fælles for alle fire typer animation, hvoraf de mest nyttige er:
- android:varighed- animationsvarighed (i millisekunder)
- android:interpolator- definerer interpolatoren til animation
- android:repeatCount- antal yderligere animationsgentagelser. Præcis yderligere, det vil sige, at animationen vil blive udført én gang alligevel. Standardværdien er "0" - det betyder, at animationen kun vil blive udført én gang. En værdi på "1" betyder, at animationen kører to gange (en gang den primære og en gang den sekundære). Værdien "-1" eller "uendelig" betyder endeløs gentagelse.
- android:repeatMode- bestemmer animationens opførsel, når den er nået til slutningen, og parameteren repeatCount er ikke lig med 0. Der er to værdier: "genstart" - animationen starter igen og "omvendt" - animationen vil gå i omvendt rækkefølge .
- android:startOffset- forsinkelse før animationen starter (i millisekunder)
9. Kombination af flere animationer
Du kan anvende flere typer animationer til et element på samme tid. Hvis vi for eksempel skriver:
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
>
Billedet ændrer gennemsigtighed på 1 sekund (fra helt gennemsigtigt til uigennemsigtigt) og roterer samtidig 360 grader.
Animationer kan indstilles til forskellige varigheder, lad os f.eks varighed = 5000 for at rotere animationen. Nu vil billedet rotere meget langsommere, og gennemsigtigheden vil stadig ændre sig på et sekund.
Ved hjælp af startOffset, kan du gøre animationerne sekventielle. Tilføj roter-attributten startOffset="1000"(det vil sige, at vi laver en forsinkelse svarende til varigheden af den første animation). Nu vil billedet først blive synligt om 1 sekund, og derefter kun rotere 360 grader.
Flere animationer kan kombineres til sæt ved hjælp af tagget. Et sådant tag vil altid være i filen og er root-tagget. Du kan indstille følgende attributter for et sæt:
- varighed(varighed), gentagelses-tilstand(gentag tilstand) - disse attributter vil blive anvendt på hver animation i sættet
- interpolator- definerer animationsinterpolatoren og shareinterpolator- om denne interpolator vil blive anvendt for hver animation i sættet (mulige værdier er "sand" og "falsk")
- startOffset(forsinkelse) - forsinkelse for hele sættet af animationer.
Desværre kan attributten ikke anvendes på sættet repeatCount, det vil sige, at det ikke virker at gentage et sæt animationer flere gange.
Sæt kan være af enhver rede.
10. Oprettelse af animation uden xml
Animation kan laves uden brug af xml, direkte i programkoden. Til dette bruges Animation-efterkommerklasserne:
1) AlphaAnimation for at skabe alfa-animation. Klassekonstruktøren ser ud
AlphaAnimation(flyd fraAlpha, flyd tilAlpha) hvor fromAlpha og toAlpha er henholdsvis de indledende og endelige gennemsigtighedsværdier (fra 0,0 til 1,0)
11.
Lad os lave en animation i koden, der, når du trykker på en knap, vil rotere billedet med en tilfældig vinkel (fra 0 til 360) og forstørre det til en tilfældig størrelse (ikke mere end to gange). Til dette formål tilføjede jeg en anden knap randomButton
randomButton.setOnClickListener(new OnClickListener() ( @Override public void onClick(View v) ( Random random = new Random (); //1 RotateAnimation rotate = new RotateAnimation (0, (float )random.nextInt(360), Animation. 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 lang varighed = rotate.computeDurationHint(); //6 float size = random.nextFloat() + 1.0; //7 ScaleAnimation scale = new ScaleAnimation(1.0f, størrelse, 1.0f, størrelse, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO , 0.5f); //8 scale.setDuration(1000); scale.setStartOffset(duration); //9 AnimationSet set = new AnimationSet (false); //10 set.addAnimation(rotate); //11 set.addAnimation (skala); image.startAnimation(sæt); //12 ) ));
1) Opret et tilfældigt objekt for at generere tilfældige tal. Du kan læse mere om Random i dokumentationen; nu er vi interesseret i int nextInt(int n) metoderne - generere et heltal i området fra 0 til n. Og float nextFloat() metoden - genererer et reelt tal fra 0 til 1.
2) Opret en rotationsanimation. Startvinkel = 0, slutvinkel = et tilfældigt tal fra 0 til 360. Animation.RELATIVE_TO_SELF betyder, at vi angiver rotationsmidtpunktet som en procentdel i forhold til bredden af elementet. Glem ikke, at værdien 1,0 svarer til 100%, hvilket betyder, at 0,5f er 50%. Dette betyder, at rotationspunktet vil være i midten af billedet.
3) Indstil animationens varighed til 1000 millisekunder (dette er 1 sekund)
4) Vi definerer gentagelsestilstanden som Animation.REVERSE, det vil sige, når vi gentager animationen, vil vi gå i omvendt rækkefølge.
5) Indstil antallet af yderligere gentagelser = 1. Det betyder, at animationen vil blive gentaget to gange, én gang i fremadgående rækkefølge og én gang baglæns.
6) Long computeDurationHint() metoden beregner, hvor længe animationen vil vare i alt. Der er en getDuration()-metode, men den returnerer simpelthen varighedsværdien, som vi indstiller med setDuration()-metoden. I vores tilfælde sætter vi varighedsværdien til 1000, og metoden getDuration() returnerer 1000 og tager ikke højde for, at animationen gentages to gange, hvilket betyder, at den faktisk vil vare 2000 millisekunder. Metoden computeDurationHint() vil beregne varigheden under hensyntagen til genforsøg og forsinkelser.
7) Beregn den nye størrelse på billedet. Værdien 1,0 er den aktuelle billedskala, så værdien 2,0 betyder, at billedet er fordoblet. Vi genererer et tal fra 0,0 til 1,0 og tilføjer 1, hvilket betyder, at vi får et tal fra 1,0 til 2,0
8) Opret en skaleringsanimation fra den aktuelle billedstørrelse til et tilfældigt genereret tal fra 1,0 til 2,0
9) Indstil en forsinkelse svarende til den samlede varighed af rotationsanimationen. Så den anden animation starter umiddelbart efter slutningen af den første
10) Opret et sæt animationer.
11) Tilføj to oprettede animationer til sættet
12) Anvend et sæt animationer på billedet
12.
En anden interessant metode i Animation-klassen
setAnimationListener(Animation.AnimationListener lytter)- indstiller en lytter til ændringer i animationstilstand. Animation.AnimationListener-grænsefladen definerer følgende metoder:
onAnimationStart (animationsanimation)- kaldes når animationen starter
onAnimationRestart (animationsanimation)- kaldet, når animationen gentages
onAnimationEnd(animationsanimation)- kaldet i slutningen af animationen
For eksempel:
anim = AnimationUtils.loadAnimation(this, R.anim.anim); anim.setAnimationListener(ny AnimationListener () ( @Override public void onAnimationEnd(Animation animation) ( Log.d("MY", "animation end" ); ) @Override public void onAnimationRepeat(Animation animation) ( Log.d("MY) " , "animation repeat" ); ) @Override public void onAnimationStart(Animation animation) ( Log.d("MY" , "animation start" ); ) ));
Vi gør ikke noget nyttigt, når vi ændrer animationstilstanden, vi skriver det bare til loggen.
Det er alt. Jeg har fortalt dig det grundlæggende, det er bedre at lære resten gennem eksperimenter :)
Kilder kan downloades her
Betegnelse af metalrør. Lad os se på betegnelserne for de mest almindelige metalrørledninger ifølge GOST. Stålvand- og gasrør i henhold til GOST Betegnelsen af røret angiver den nominelle diameter, længde (ved brug af rør af målt længde) og vægtykkelse. Lad os overveje et eksempel på betegnelsen af et rør med en nominel diameter på 32 mm, en vægtykkelse på 2,8 mm, uden zinkbelægning: Rør 32x2,8 GOST Tilstedeværelsen af en zinkbelægning er angivet med bogstavet C, som er placeret efter ordet "Rør".
Om nødvendigt er et mærke, der angiver tilstedeværelsen af gevind, angivet i rørbetegnelsen. Mærkning af stålrør i henhold til GOST udføres på fabrikken efter produktion og indeholder oplysninger om størrelse, kvalitet af stål, som røret er lavet af, samt producentens varemærke. Størrelsen af mærkets bogstaver og tal er direkte proportional med produktets størrelse og kan påføres ved hjælp af flere metoder.
De mest almindelige er branding og vandfast maling. Kontroltyper og deres betegnelse i produktmærkning er beskrevet i tabellen (tabel); Næste punkt"" angiver vægtykkelse i millimeter; Den fjerde værdi angiver produktets længde i millimeter fra snit til snit, i dette tilfælde er det "".
Sådan dechifreres markeringerne af stålrør: diameter, stålkvalitet og andre indikatorer i henhold til GOST. Symbolerne trykt på stålrøret giver omfattende information om produkter.
Mærkning er en slags pas for et produkt, hvorfra det bliver klart, hvem, hvor og til hvilke formål det er fremstillet. Denne artikel vil fortælle dig, hvordan du korrekt dechifrerer alle markeringssymboler på rør.
Bemærk. Mærkningen af stål (og støbejern) rør er reguleret af GOST nr. af året. Dette dokument definerer alle nuancerne ved at anvende forklarende inskriptioner, deres størrelser, afstande mellem tal osv.
Koldedeformerede sømløse stålrør GOST (sortiment) Denne standard gælder for koldformede sømløse rør generelle formål lavet af kulstof og legeret stål. Diameter: 5 - mm. I rørsymboler er indekset A eller B placeret før stålkvaliteten. Rør fremstilles enten varmebehandlet eller uden varmebehandling.
Enderne af rørene skal skæres i rette vinkler. Metoder til mærkning af stålrør: GOST-standarder, eksempler på afkodning symboler. Ved at læse tallene på produktet kan en specialist bestemme størrelsen på røret, dets type, stålkvalitet, styrke, producent og nogle andre parametre for produktet.
Mærkning af stålrør særligt formål indeholder yderligere markeringer. Produkter til særlige formål omfatter: Rør lavet af legeret stålkvaliteter. 4. REFERENCER Regulative og tekniske dokumenter. Betegnelse NTD. som linket er givet til. W s g -80 GOST yu S1 Varenummer. Ændring nr. 2 GOST - 91 Elektrosvejsede ligesvejsede stålrør.
Sortiment vedtaget af Interstate Council for Standardization, Metrology and Certification ved korrespondance (protokol nr. 45- dateret) Registreret af Bureau of IGU Standards No. De nationale standardiseringsorganer i følgende stater stemte for vedtagelse af ændringen: BY, KG , RU, TJ [alfakoder 2 ifølge MK (ISO)].
Salg og køb. Betegnelse for stålrør. El-svejste stålrør med lige søm. Udvalg. GOST IPK Forlag med standarder. Statsstandard for Unionen af USSR. Direkte søm elektrisk svejste stålrør. Med ornament. Elektrisk svejste stålsvejsesmøremidler. Rækkevidde. GOST Introduktionsdato 1. Denne standard etablerer en række elektrisk-svejsede stålrør med lige søm.
2. Dimensionerne på rørene skal svare til tabellen. 1. 3. I henhold til rørets længde er de fremstillet: af umålt længde Betegnelse på den videnskabelige og tekniske dokumentation, hvortil der henvises. Varenummer. GOST
Kategorier Post navigationGod dag til alle. Jeg vil gerne dedikere dette indlæg til emnet fragmenter til Android. Der er allerede oversættelser og nogle artikler om Habré, der nævner, hvordan man begynder at arbejde med fragmenter til Android. For eksempel artikel. Den indeholder en beskrivelse af, hvad fragmenter er, og i hvilken version af Android de findes, så dem, der endnu ikke er nået til den, kan læse den, hvis de ønsker det, men det vil jeg ikke genfortælle i mit indlæg. Så jeg kommer lige til sagen.
Begyndelse af arbejdet
Lad mig lige kort sige, at fragmenter er brugergrænsefladekomponenter, der kan bruges ved hjælp af aktivitetsklassen til at vise brugerdata, men de livscyklus er ikke afhængig af ham. Funktionaliteten fra fragmenter har bredere funktionalitet til at arbejde med dem end Activity, så deres brug er af ikke ringe betydning for udviklere, hvis de ønsker, at deres applikation skal have en brugergrænseflade, der er mere moderne efter nutidens standarder.Lad os nu komme til punktet med indlægget. Google-udviklere Fragmenter var efter min mening udstyret med fremragende støtte til animation for at vise selve fragmentet. Dette vil blive diskuteret yderligere. Jeg søgte Habr efter indlæg om dette emne, men jeg fandt ikke noget, så nu vil jeg dele min viden.
Oprettelse af et projekt
Lad os lave et lille projekt. Jeg har lavet et projekt til min Samsung Nexus S, jeg har Android version 4.1.2 der, hvilket er hvad jeg faktisk brugte (Api Level 16). Jeg kaldte selve projektet FragmentsAnimationTest.Til demonstrationen skal vi bruge hovedaktiviteten og dens layout, et par fragmenter, hver med sit eget layout, og et par xml-filer mere til selve animationen, som jeg vil tale om senere.
Applikationen vil se sådan ud: et af fragmenterne vil blive vist på skærmen, skift mellem dem vil ske vha. almindelig knap, og følgelig vil selve skiftet af fragmenter blive ledsaget af animationseffekter.
Lad os først arrangere hovedaktivitetens elementer i filen activity_main.xml:
Fra koden kan du se, at hovedlayoutet bruges - RelativeLayout, hvilket er ret praktisk, når du arbejder med fragmenter; to standard FrameLayout-elementer er placeret i det - faktisk vil det være en beholder til fragmenter og en knap, der vil blive brugt at skifte fragmenter indbyrdes. For nu skulle alt være ekstremt enkelt.
Lad os derefter gå videre til vores fragmenter. Lad os lave opmærkning til dem og klasserne selv:
fragment1.xml
Fragment2.xml
For begge fragmenter er koden næsten den samme, den eneste forskel er den tekst, der vil blive vist i selve fragmentet for at identificere det og baggrundsfarven, så animationen er tydeligt synlig.
Fragment1.java
public class Fragment1 udvider Fragment ( @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) (retur inflater.inflate(R.layout.fragment_1, null); ) )
Fragment2.java
public class Fragment2 udvider Fragment( @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) (retur inflater.inflate(R.layout.fragment_2, null); ) )
I timerne skal alt også være klart, hvis du er bekendt med emnet for fragmenterne. De angiver blot, hvilken nøjagtig udeladelse der vil blive brugt, når du viser et specifikt fragment, og det er alt.
Lad os nu komme til den lækre del. Lad os arbejde med hovedaktivitetsklassen, her er dens kode:
public class MainActivity udvider Activity ( privat Fragment fragment2; privat Fragment fragment1; private FragmentTransaction ft; @Override protected void onCreate(Bundle savedInstanceState) ( super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); fragment1() new ; fragment2 = new Fragment2(); ft = getFragmentManager().beginTransaction(); ft.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_in_right); // ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_REplace(); 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(fragment1.isVisible ))( ft.replace(R.id.fragCont, fragment2); )else( ft.replace(R.id.fragCont, fragment1); ) ft.commit(); ) )); ))
Lad os se på, hvad der præcist sker i vores aktivitet. Først oprettes begge fragmenter, som, som allerede nævnt, skiftevis vil ændre hinanden. Dernæst angiver vi med linjen ft = getFragmentManager().beginTransaction() at vi får en FragmentTransaction, som vi kan interagere med vores fragmenter med, men det er alt sammen i artiklen, som jeg nævnte tidligere. Inden jeg går videre til analysen af følgende kode, vil jeg lave en lille digression.
Der er to muligheder for at oprette animationer til visning af fragmenter:
- Den første metode er at forbinde standard animation ved hjælp af setTransition(int transit) metoden. FragmentTransaction-klassen har flere foruddefinerede animationer.
- Den anden metode er præcis det, der interesserer os i dette emne, implementeringen af brugerdefineret animation. Udført ved hjælp af setCustomAnimations() metoden
Et par aktiekommentarer er, så du kan prøve at lege med den forudbeskrevne animation, bare fjern dem og kommentere den forrige linje - ft.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_in_right), i begge tilfælde, selvom dette er ikke nødvendigt.
Lad os analysere aktivitetskoden til ende og gå videre til at skabe selve animationen.
Efter indstilling af animationen vises fragmentet, tilføjes til stakken, og transaktionen er fuldført for at vise alle ændringer. Derefter initialiserer vi vores knap og knytter en knap-klik-hændelseslytter til den, hvori der er kode til at ændre fragmenter. Når knappen trykkes, starter vi en transaktion, forbinder animation og ændrer fragmentet til det modsatte vist i i øjeblikket. Koden er enkel, så den kræver ikke en dyb forklaring.
Oprettelse af animation
Lad os gå videre til hoveddelen af vores emne. Lad os lære, hvordan man laver selve animationen. Den måde, vi laver animationer på her, er lidt anderledes end, hvordan vi er vant til at gøre det i tidligere versioner af Android. Implementeringen foregår som følger. Først skal du oprette en animatormappe i applikationsressourcemappen, den vil se sådan ud - res/animator/. Her skal vi lægge xml-filer, der vil beskrive præcis, hvordan animationen skal afspilles. Lad os sætte dem der:slide_in_left.xml
Og slide_in_right.xml
Lad os nu se på dem i detaljer. Selve elementerne i de visuelle effekter er beskrevet i objectAnimator-tagget; hvert sådant tag beskriver beskrivelsen af en ny animationseffekt. Lad os nu se på egenskaberne selv. Den første attribut i filen slide_in_left.xml er interpolator, den har flere værdier, du kan lære mere om dem i Property Animation dokumentationen. Interpolatoren er ansvarlig for gengivelsen på en bestemt måde for en vis tid vores fragment. Dernæst har vi attributten propertyName, den indikerer hvilken egenskab af fragmentet vi vil ændre under animation; i vores eksempel kommer y først, og valueType indikerer hvilken type parameter vi ændrer. I bogen Pro Android 4 denne situation argumenteres af det faktum, at hvis du ser på setX()-metoden i View-klassen, bliver det klart, at den tager en float-typeværdi, det samme er tilfældet med setY()-metoden, deraf floatType-værdien.
Dernæst kommer de ikke uvæsentlige attributter valueFrom og valueTo, de angiver fra hvilken værdi der skal ændres værdien angivet i ejendomsnavn, i vores første tilfælde er det y. Hvis parameteren valueFrom ikke er angivet, tages værdien lig med den aktuelle. I vores tilfælde er valueFrom lig med -1280, dette betyder, at bevægelsen af fragmentet langs y-aksen starter fra værdien -1280, denne værdi blev valgt på grund af det faktum, at den er placeret uden for enhedens skærm og bevægelsen vil forekomme, indtil y-værdien bliver lig 0 for det øverste venstre hjørne af vores fragment i 1500 millisekunder. Og endelig specificerer duration-attributten præcis, hvor længe vores animerede effekt vil vare i millisekunder.
Og den sidste nuance, som jeg vil beskrive. Når du ser på nogen af animationsbeskrivelsesfilerne, kan du se sæt-tagget, som indeholder alle animationseffekterne; det tjener til at kombinere effekter eller adskille dem. Slide_in_right.xml-filen bruger ordensattributten i set-tagget, i vores tilfælde har den værdien sammen, hvilket betyder at afspille effekterne samtidigt, i modsætning til det er der en værdi sekventielt, som kræver, at effekterne vises sekventielt i animation, hvilket er meget praktisk i nogle tilfælde.
Det er alt. Filen slide_in_right.xml giver et eksempel på, hvordan du kan bruge andre egenskaber til animation, såsom alfakanalen. Håber denne artikel nyttigt for dem, der bekymrer sig om, hvordan deres applikation vil se ud.
Som du selv forstår, kære Habrausere, vil screenshots ikke kunne vise resultatet af arbejdet.
Litteraturen og kilderne, der blev brugt ved skrivningen af indlægget, blev nævnt under selve artiklen.
Fra og med Android 4.4 har udviklere tilføjet ekstra værktøj at lave animationer - Transitions Framework. Det var oprindeligt beregnet til at skabe animationer for at ændre tilstanden af en applikation ved at manipulere flere visninger. Med udgivelsen af Android 5.0 blev animationssættet, der var tilgængeligt til brug, udvidet til at svare til det samtidig introducerede Material Design-koncept.
Transitions Framework giver dig mulighed for hurtigt og smertefrit at skabe forskellige animationer. Derfor var det umuligt at ignorere dette værktøjssæt under arbejdet med iFunny. Læserne inviteres til særlig situation ved at bruge Transitions API - skabe animation af overgangen mellem aktivitet med en "sømløs" effekt.
Fra et visuelt synspunkt kan overgangsanimationerne mellem aktiviteter præsenteret i Transitions Framework opdeles i to typer: almindelige animationer og animationer med et fælles element. Konceptet med animation med et fælles element er demonstreret i en figur, der ærligt er stjålet fra developer.android.com. 1. De fælles elementer på den er avataren og kontaktens navn.
Ris. 1. Animation af overgang mellem Aktivitet med fælles elementer
Men ingen kan lide lange introduktioner, så lad os gå direkte til historien om, hvordan animationerne blev skabt af denne type i iFunny-appen. Som et første eksempel kan du overveje animationen vist i fig. 2. For at bruge det har vi brug for Android versioner 5.0 og højere.
Fig. 2. Animation af overgangen mellem Aktivitet på brugergodkendelsesskærmen
Fra brugerens synspunkt er der ikke noget usædvanligt her: én skærm, simpel animation. Men som du måske har gættet, er "under motorhjelmen" overgangen mellem to skærme med ét fælles element.
Det første skridt til at skabe en sådan overgang er, mærkeligt nok, at vælge netop dette element og bestemme dets placering i layoutet af begge aktiviteter. Herefter skal du tilføje attributten android:transitionName til beskrivelsen af hver visning, der viser det valgte element, og også tildele dem et android:id, hvis det mangler.
I vores tilfælde er disse almindelige ImageViews i følgende form:
Der er to ting, der er værd at bemærke her vigtige punkter. For det første skal begge ImageViews indstilles til det samme transitionName, hvilket er logisk. For det andet, da vi bruger ImageView, skal deres indhold være det samme, da brug af to forskellige ressourcer kan føre til uventede konsekvenser (i det mindste til at den animerede visning blinker i begyndelsen og slutningen af animationen).
I det andet trin skal du tilføje muligheder for den lancerede (anden) aktivitet, hvilket indikerer, at en animation skal startes, når den starter.
Bemærk. Med "anden" mener vi den lancerede aktivitet, hvortil overgangen skal udføres, og med "først" mener vi den lancerede aktivitet.
Dette gøres som følger:
Bundle bundle = null; if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) ( View v = activity.findViewById(R.id.auth_logo); if (v != null) ( ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(activity) , v, activity.getString(R.string.email_auth_transition)); bundle = options.toBundle(); ) ) Intent hensigt = new Intent(activity, SecondActivity.class); if (bundle == null) ( activity.startActivity(intent); ) else (activity.startActivity(intent, bundle); )
I følgende liste:
- R.id.auth_logo - ImageView fra den første aktivitet, brugt i animation;
- aktivitet - første aktivitet;
- R.string.email_auth_transition - en etiket, der tidligere var tilbage i layoutet af begge ImageViews;
- SecondActivity.class - anden aktivitet.
På tredje trin er det nødvendigt at beskrive overgangsanimationen, dvs. angive den sti, som den animerede visning gennemgår, og transformationen af selve visningen. Til dette vil vi skabe separat fil projectName/src/main/res/transitions/email_auth_transition.xml med følgende indhold:
Lidt teori. TransitionSet-tagget er beregnet til at beskrive flere transformationer, der anvendes på den animerede visning på én gang. Parameteren transitionOrdering styrer den rækkefølge, som disse transformationer anvendes i. I vores tilfælde anvendes de samtidigt. Der er flere typer forudbyggede transformationer i overgangsrammen. MED fuld liste kan findes på denne side. Vi vil fokusere på to specifikke: changeBounds og changeImageTransform.
Den første er til at transformere størrelsen af visningen. Den anden fungerer kun med ImageView og giver dig i forbindelse med den første mulighed for at ændre ikke kun størrelsen, men også formen på ImageView. Ved hjælp af transformationsdataene opnår vi outputanimationen for at ændre billedstørrelsen, vist i fig. 2. Hvis du ikke angiver bevægelsestypen for den animerede visning, vil den bevæge sig langs den korteste vej. Lad os se på en mere interessant transportmetode i det andet eksempel.
Det sidste trin i at skabe en animation er at erklære den i temaerne for begge aktiviteter. For at gøre dette skal du redigere beskrivelsen af temaerne som følger (eller oprette nye i mappen projectName/src/main/res/values-v22/theme.xml):
Her:
- android:windowActivityTransitions muliggør overgangsanimationer;
- android:windowSharedElementEnterTransition peger på en fil, der beskriver animationen af overgangen fra den første aktivitet til den anden;
- android:windowSharedElementExitTransition peger på en fil, der beskriver overgangsanimationen, når du vender tilbage fra den anden aktivitet til den første.
Så for at lave en animation af overgangen fra aktivitet til aktivitet skal du:
- Beskriv animationerne (i vores tilfælde i en xml-fil);
- Tilføj disse animationer til xml-beskrivelsen af aktivitetstemaet;
- Marker det animerede fælles element (View) i markeringen;
- Når du starter den anden aktivitet, skal du angive i startparametrene, at den skal aktivere overgangsanimation.
Fig. 3. Animation af overgang fra kommentarer til brugerprofil
Alle overgangstrinene beskrevet ovenfor gælder også for denne animation. Her er forvandlingen fælles element implementeret lidt anderledes. Listen nedenfor beskriver, hvordan man flytter et generisk element "langs en bue", mens dets størrelse ændres.
Hvad er vanskeligheden ved det andet eksempel? I det første tilfælde blev der brugt et billede fra selve applikationens ressourcer, men her downloades billedet fra netværket. For kommentarer er brugerens avatarbillede desuden taget i en lavere opløsning end for profilen. Derfor er det nødvendigt ikke kun at give den anden aktivitet adgang til billedet, der blev brugt i den første, men også at indlæse det påkrævede billede i højere kvalitet efter afslutningen af animationen. Dette skaber to problemer.
For at løse den første kan du selv cache billedet til disken eller sende dets adresse i parameteren for den anden aktivitet. Løsningen på dette problem blev dog flyttet til det bibliotek, der blev brugt i applikationen til at indlæse billeder - Glide. Når du indlæser et billede, skal du blot tilføje diskCacheStrategy(DiskCacheStrategy.SOURCE) parameteren, og det vil blive cachelagt af selve biblioteket (relevant for Glide version 3.x). Derfor, når vi får adgang til denne ressource igen fra den anden aktivitet, vil den cachelagrede fil blive brugt, hvilket vil hjælpe os med at undgå at blinke i den animerede ImageView.
Det andet problem er også løst ganske enkelt. Mens overgangsanimationen udføres, downloades brugerprofilen sammen med avataren i en højere opløsning fra netværket og venter på dens færdiggørelse. Når begge betingelser er opfyldt (animation fuldført og indlæsning fuldført), opdateres brugerens avatar. Du kan opnå denne adfærd, hvis du bruger en speciel Listener, som implementerer tilbagekald, der kaldes, når animationsstatus ændres. For at gøre dette vil vi i fragmentet, der hører til den anden aktivitet, indstille denne samme lytter:
@Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) ( super.onViewCreated(view, savedInstanceState); if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) ( getActivity().getWindow( ).getSharedElementEnterTransition() .addListener(mEnterTransitionListener); ) setAvatar(); )
Her er hvad der sker:
- Ved at bruge getSharedElementEnterTransition().addListener() sættes en lytter til at animere udseendet af aktiviteten;
- Metoden setAvatar() forsøger at indlæse og installere en avatar (som allerede er i cachen).
Private Transition.TransitionListener mEnterTransitionListener = ny Transition.TransitionListener() ( @Override public void onTransitionStart(Transition transition) ( ) @Override public void onTransitionEnd(Transition transition) ( onProfileUpdated(); ) @Override public void onTransitionCance ((TransitionCance) transition) @Override public void onTransitionPause(Transition transition) ( ) @Override public void onTransitionResume(Transition transition) ( ) );
I onProfileUpdated() metoden opdaterer vi profilindholdet, inkl. og avatar.
Det er værd at nævne særskilt tilfældet, når et fælles element forsvinder fra skærmen. Dens ejendommelighed er, at i modsætning til (eller måske ifølge) logik, vil overgangsanimationen stadig blive udført og vil se ret sjov ud (fig. 4).
Ris. 4. Animation af tilbagevenden fra profilen til kommentarerne
For at undgå denne adfærd er det nok at indstille den til en anden synlighed end View.VISIBLE, når det fælles element forlader skærmen.
Overordnet set kan vi sige, at Transitions Framework er et enkelt og kraftfuldt værktøj til at skabe animationer. Det er ikke kun begrænset til overgangsanimationer mellem aktivitet - artiklen betragtede kun et særligt tilfælde af dens brug. Det er også værd at bemærke, at ud over de transformationer, der leveres, er det muligt at oprette din egen, men dette er en helt anden historie, der er værdig til et separat indlæg.
P.S. Og du kan læse om, hvordan animationer til iFunny blev opfundet.
Tags:
- android
- materiale design
I et stykke tid har det i Android været muligt at bruge vektorressourcer i stedet for png-slices. Denne mulighed dukkede op med udgivelsen af Android 5.0 Lollipop og API 21. Til tidligere versioner af systemet kan vi bruge AppCompat (kompatibilitetsbibliotek), takket være hvilket en statisk vektor vil fungere med API 7 (Android 2.1), og en animeret en med API 11 (Android 3.0 Honeycomb).
Vektorressourcer, i modsætning til konventionel udskæring, fylder omkring 10 gange mindre. Der er ingen grund til at tilpasse grafik til forskellige skærmtætheder. Derudover kan du genbruge ressourcen i forskellige sammenhænge, størrelser og farver.
En anden vigtig fordel er muligheden for at tilføje animation. Ja, selvfølgelig kan animation laves ved hjælp af png — for eksempel sprite-animation, men en sådan animation vil optage titusinder gange mere plads under hensyntagen til understøttelsen af alle opløsninger.
Vektor til Android?
Før du begynder at oprette vektoraktiver, skal du forstå, hvad en vektor er på Android. Det er meget vigtigt at forstå strukturen, fordi der i øjeblikket ikke er nogen værktøjer til praktisk skabelse og visuel kontrol af animation.
Desværre (eller heldigvis) kan du ikke bruge svg-filer direkte i Android, ved i det mindste uden brug af tredjepartsbiblioteker. Årsagen er meget enkel og er, at SVG-formatet er meget komplekst og rigt på muligheder, og at understøtte en sådan rig funktionalitet er kompleks og ikke praktisk til så simple ting som ikoner, og glem ikke problemet med ydeevne og kompatibilitet. Derfor bruger de i Android et enklere format, som ikke desto mindre på mange måder ligner svg.
Vektorgrafik er repræsenteret som to klasser, VectorDrawable og AnimatedVectorDrawable. Fra navnet på klasserne er det klart, at den første er ansvarlig for en statisk vektor, og den anden for dens animation. Klasser er beskrevet af en almindelig XML-ressource.
Lad os først se på en VectorDrawable, som har følgende struktur:
I element
For at tilføje animation bruger vi ObjectAnimator-klassen, som vi blot anvender på VectorDrawable-objekter. Vi kan anvende animation både til en generel gruppe og til en specifik gruppe
Tidligere, for at implementere animation i en applikation, var det nødvendigt at bruge mindst 3 xml-filer: 1 fil til VectorDrawable, der skal animeres, en anden til animatoren, der beskriver animationen, og den sidste fil, der kombinerer animatoren og VectorDrawable direkte . Jo mere kompleks animationen er, jo flere filer skulle der oprettes, hvilket ofte førte til forvirring.
På Google I/O 2016 blev et nyt format introduceret - XML-pakken. Det giver dig mulighed for at beskrive vektoranimation i én fil.
Eksempel XML-pakke
Grundlæggende er vi alle nødvendige oplysninger placeret i AnimatedVectorDrawable. Det er meget nemt at samle en sådan fil, stykkerne er fremhævet på billedet, som blot skæres ud fra de tilsvarende ressourcer og indsættes mellem specielle aapt-tags.
Forberedelse af en vektor til Android
Først har vi brug for nogen grafik editor, som kan udskrive en svg-fil. Heldigvis er der rigtig mange af dem: Photoshop, Illustrator, Sketch, Inkscape, Affinity Designer osv.
Når du opretter et vektorbillede, skal du bruge de mest grundlæggende værktøjer, da skygger og andre filtre simpelthen ikke fungerer.
Det gjorde jeg for eksempel simpelt ikon slot og opdelte det i to former (grupper) til efterfølgende animation. Vi gemmer det som svg og sørg for at kontrollere korrektheden af eksporten. Meget ofte opstår der problemer med slagtilfælde og overdreven indlejring af genstande. Forsøg som regel at kombinere alt til ét objekt så meget som muligt, og oversæt streg til form(kontur).
Konverter SVG til XML
Der er flere måder at konvertere en svg-fil til xml.
Den første måde er at gøre alt i hånden. Dette er selvfølgelig ikke særlig bekvemt, men der er ikke noget kompliceret her. Bare overfør stykker fra svg til xml ved hjælp af rigtige navne parametre. Nedenfor har jeg fremhævet stykker, der er næsten fuldstændig identiske.
Anden måde — I Android Studio har et Vector Asset Studio-værktøj, der giver dig mulighed for automatisk at udføre oversættelsen SVG-fil og i XML. Du kan vælge ressourcer fra ikonbiblioteket eller angive din egen SVG-fil. Takket være forhåndsvisningen kan du straks vurdere korrektheden af eksporten. Spise nyttige indstillinger.
Den tredje måde — er at bruge f.eks. onlineværktøjer