Van ontwerp tot Android, deel 2

Het is lang geleden sinds mijn vorige bericht, sindsdien zijn er veel dingen gebeurd, maar eindelijk is het hier. Ik hoop dat je ervan geniet!.

Dit is een nieuw verhaal in mijn reeks artikelen genaamd 'Van ontwerp tot android', als je het eerste deel van deze serie herinnert, kies ik een ontwerpconcept dat ik interessant vind en ik probeer het te implementeren op Android, met focus op enkele interessante onderwerpen onderweg vanuit het perspectief van mijn Android-ontwikkelaar.

Alle code waarnaar in dit bericht wordt verwezen, is te vinden in de repository van deze Github

Dit is het concept dat ik voor dit onderdeel heb gekozen:

Google Business - Slider van Johny Vino

Ik gebruikte opnieuw een concept van Johny Vino.

Probeer een seconde te stoppen om als Android-ontwikkelaar uit te zoeken hoe je dat scherm kunt implementeren.

Als je twee van de volgende punten zag, was je het misschien met me eens, op het eerste gezicht kwamen er twee delen bij me op:

  • Hoe de animatie van het gebouw natuurlijk te implementeren.
  • Die zoekbalk is misschien niet zo triviaal als hij zou moeten zijn

Het gebouw animeren

Laten we deze oefening op een perfecte omgeving zetten, we kunnen onze ontwerper (s) vragen om de animatie te maken. Na misschien, sommige After Effects werken + de plug-in van Bodymovin, zouden ze ons de gewenste geanimeerde vector kunnen geven.

Of ... we hebben misschien helemaal geen ontwerper, en jij bent een dappere en eenzame ontwikkelaar die dit zonder veel ontwerpvaardigheden moet doen, laten we dat pad proberen.

Werken met vectoren

Met wat klein werk aan een op vectoren gebaseerd hulpmiddel zoals Sketch of BoxySvg kunnen we het gebouwimage gemakkelijk vectoriseren. Het groeperen van die delen waarvan de animaties in groepen worden geanimeerd, zal nuttig zijn voor een volgend punt.

De gewenste afbeelding op Sketch maken

Vervolgens komt er een nieuwe geweldige tool op de markt, en deze is Shape Shifter van Alex Lockwood. Deze geweldige tool helpt je om op SVG gebaseerde afbeeldingen te animeren en die animaties te exporteren naar een AVD onder andere formaten.

Shape Shifter

Na het creëren van het gewenste effect met een paar klikken, kunnen we onze nieuwe geanimeerde vector-tekentafel exporteren, in Android Studio plakken, aan een ImageView binden en we zijn klaar !.

(img_building.drawable als Animatable) .start ()
ShapeFilter wordt geëxporteerd op een Android-apparaat

Ja, geweldig toch ?! We hebben zojuist moeiteloos een geweldige animatie gebouwd, maar als we opnieuw naar het concept van Johny Vino kijken, hebben we kleine details gemist. De animatie wordt afgehandeld door een schuifbalk (bekend als Seekbar op Android) die de status van de animatie afhandelt, afhankelijk van de voortgang van de balk.

Dus wat we nodig hebben is tot nu toe om de voortgang van de animatie in een AVD in te stellen. Nou ... dat wordt momenteel niet ondersteund door wat ik heb gezien, (Lottie doet). We hebben gewoon de beschikking over methoden zoals .start (), .stop () en reset ().

Op dit punt kunnen we het volgende proberen:

Of blijf doorgaan, laten we nog even doorgaan.

Geanimeerde selector Drawables

In ons huidige punt hebben we een animatie die moet worden opgedragen om naar een specifiek frame te gaan wanneer de SeekBar een specifieke positie bereikt. Met andere woorden, we hebben een aantal toestanden tijdens de animatie.

Laten we enkele attributen declareren voor het definiëren van deze frames of staten.


    
    
    
    
    
    

Laat me in dit punt een misschien niet zo bekend tekenbaar maken, de AnimatedStateListDrawable die onze dag volledig zal redden.

Laten we eens kijken naar de Android-documentatie:

Drawable met een set Drawable keyframes waarbij het huidig ​​weergegeven keyframe wordt gekozen op basis van de huidige statusset. Animaties tussen hoofdframes kunnen optioneel worden gedefinieerd met behulp van overgangselementen.
Dit teken kan worden gedefinieerd in een XML-bestand met het element . Elk hoofdframe Drawable wordt gedefinieerd in een genest -element. Overgangen worden gedefinieerd in een genest element .

Ziet er enigszins uit wat we zoeken, toch? We kunnen enkele definiëren die de verschillende frames in onze animatie identificeren, en overgangen voor de overgang van een item naar een ander.

Omdat elke tag ons frame zou vertegenwoordigen, zullen we er drie definiëren, elk samengesteld door een vector-tekenbaar.

betekenbare / vd_building1.xml
betekenbare / vd_building2.xml
betekenbare / vd_building3.xml

En elke zal weergeven hoe een overgaat in een andere, we hebben er 4 nodig om alle frames heen en weer over te schakelen.

Met de bovengenoemde Shape Shifter kunnen we eenvoudig de vereiste AVD's exporteren naar Android Studio, die als overgangen werken in de AnimationStateListDrawable.

betekenbare / avd_building_1_2
betekenbare / avd_building_2_3
betekenbare / avd_building_3_2
betekenbare / avd_building_2_1
avd_building_1_2.xmlavd_building_2_3.xml

En tot slot de hele AnimatedStateDrawable die we zojuist hebben gebouwd:




    

    

    

    

    

    

    

Door onze activiteit en onze lay-out een beetje aan te passen, hebben we deze verbazingwekkende AnimatedSelectorDrawable in een ImageView ingesteld als bronbron en met behulp van de methode setImageState met de gewenste status, werkt de animatie op magische wijze zoals verwacht.

private val STATE_ZERO = intArrayOf (
        R.attr.state_zero, -R.attr.state_one, -R.attr.state_two
)

private val STATE_ONE = intArrayOf (
        -R.attr.state_zero, R.attr.state_one, -R.attr.state_two
)

private val STATE_TWO = intArrayOf (
        -R.attr.state_zero, -R.attr.state_one, R.attr.state_two
)
privéplezier opSeekProgressChanged (positie: Int) {
    val max = seekbar.max

    val businessType = wanneer (positie) {
        in 0..max / 3 -> STATE_ZERO
        in 10..max / 2 -> STATE_ONE
        in 20..max / 1 -> STATE_TWO
        anders -> gooi IllegalStateException ()
    }

    imageView.setImageState (businessType, true)
}

Resultaat:

De duim van de zoekbalk animeren

Yai! Tot nu toe hebben we een van mijn twee hot points bereikt, de tweede is erin slagen de grootte van de Seekbar-duim te animeren tijdens de voortgang, zoals Johny Vino doet in zijn concept:

Grootte van de duim van de zoekbalk bij het slepen

We kunnen hier twee gedragingen onderscheiden:

  • De duimgrootte wordt op een of andere manier vergroot in verband met de voortgang
  • Bij het vrijgeven wordt een soort van doorschietanimatie uitgevoerd

Een bezoek aan de ScaleDrawable

Een ander onbekend teken (althans voor mij) is de ScaleDrawable, laten we de Android-documentatie opnieuw raadplegen:

Een Drawable dat de grootte van een ander Drawable wijzigt op basis van de huidige niveauwaarde. U kunt bepalen hoeveel het tekenbare kind in breedte en hoogte verandert op basis van het niveau, evenals een zwaartekracht om te bepalen waar het in de algehele container wordt geplaatst. Meestal gebruikt om dingen zoals voortgangsbalken te implementeren.
Het standaardniveau kan worden opgegeven vanuit XML met behulp van de eigenschap android: level. Als deze eigenschap niet is opgegeven, is het standaardniveau 0, wat overeenkomt met nulhoogte en / of breedte, afhankelijk van de waarden die zijn opgegeven voor android.R.styleable # ScaleDrawable_scaleWidth scaleWidthand android.R.styleable # ScaleDrawable_scaleHeight scaleHeight. Tijdens runtime kan het niveau worden ingesteld via setLevel (int).

Het lijkt er dus op dat we een soort tekenbaar kunnen definiëren dat verwijst naar een ander tekenbaar, een niveau en een schaalfactor. Als we de voortgang van de balk aan dat niveau koppelen, zou het moeten werken, toch?

Laten we een lijst met lagen met tekentekens definiëren en, omdat we alleen het blauwe gedeelte willen schalen, zullen we het in een ScaleDrawable verpakken.



    
        

            
              
                  

                  
              
            
        
    
    
        
            
        
    

Zoals u zult zien, kunnen we met behulp van de tool vereiste attributen direct in de inline plaatsen

thumb <layer-list> met een ScaleDrawable

Nu hoeven we alleen nog maar onze activiteit aan te passen om het niveau van de ScaleDrawable in te stellen, precies wanneer de voortgang van de SeekBar verandert, merk ook op wat leuk is dat we de eigenschap level van de Drawable van de duim kunnen gebruiken.

privéplezier opSeekProgressChanged (positie: Int) {
    // ...
    
    ((seekbar.thumb als LayerDrawable)). level =
            (positie * (SCALE_MAX / seekbar.max))
}

En het resultaat:

Nu moeten we gewoon de duim animeren bij het loslaten, we kunnen dat verwijderen door gebruik te maken van de ScaleDrawable en een ValueAnimator.

privéplezier animateThumbRelease () {
    val thumb = seekbar.thumb
    val initLevel = thumb.level
    val maxLevel = thumb.level * THUMB_RELEASE_SCALE_FACTOR
    val animator = ValueAnimator.ofInt (
            initLevel, maxLevel, initLevel)

    met (animator) {
        interpolator = OVERSHOOT
        duur = THUMB_SCALE_DURATION

        addUpdateListener {
            thumb.level = it.animatedValue als Int
        }

        begin()
    }
}

Resultaat:

Afsluiten

Op dit punt hebben we het probleem met de animatie opgelost, en daarna die met de Seekbar, met een paar meer triviale aanpassingen zoals het maken van een AVD voor de bewegende wolken, het gebruik van het nieuwe lettertype als hulpmiddelen voor onze teksten en het toevoegen van een fris nieuw adaptief pictogram, we hebben iets wat erg lijkt op het concept van de Johny Vino.

Ik hoop dat je het leuk vond tijdens de weg en, als je me moet vermoorden omdat er iets is, doe het dan alsjeblieft met een leuke opmerking en een agressieve emoji.

Eindresultaat:

Github Repository

hier

Referenties

  • VectorDrawable adaptieve pictogrammen, Ian Lake
  • Adaptieve pictogrammen ontwerpen, Nick Butcher
  • Shape Shifter, Alex Lockwood
  • Een inleiding tot pictogramanimatietechnieken, Alex Lockwood
  • adp-delightful-details, Alex Lockwood
  • Hoe we een mooie animatie ontwerpen, Jeremie Martinez