Komme i gang med Xamarin.Forms Tilpasse brukergrensesnitt

1. Stille inn scenen

Når du lager programmer med Xamarin.Forms, vil du uten tvil som enkelheten til å skape brukergrensesnitt. Ved å bruke Xamarin.Forms, kan du bruke samme terminologi for kontroller på tvers av flere plattformer.

Selv om dette konseptet kan være veldig kraftig, som en designer eller en utvikler, kan det være noe begrensende. Det kan virke som om vi er tvunget til å bruke de opprinnelige brukergrensesnittkontrollene som følger med hver av plattformene uten mulighet til å legge til tilpasning. Det er ikke slik det er.

For å komme inn i prosessen med å tilpasse brukergrensesnittet for bestemte plattformer, må du først forstå renderingsprosessen til Xamarin.Forms.

2. Kontroller rendering

Når det kommer til å bruke Xamarin.Forms for å skape et brukergrensesnitt for mobilplattformen din, er det to viktige stykker til puslespillet du må forstå.

Element

Det første stykket av puslespillet er element. Du kan tenke på et element som plattformens agnostiske definisjon av en kontroll i Xamarin.Forms. Hvis du har lest gjennom dokumentasjonen i det hele tatt, vil du vite at disse kontrollene også refereres til som Utsikt objekter. For å være enda mer spesifikk, kommer hvert element i Xamarin.Forms fra Utsikt klasse.

Disse elementene brukes til å beskrive et visuelt element. Elementene gir en plattform agnostisk definisjon av egenskaper for hvordan kontrollen skal se ut og oppføre seg. Et element på sin egen kan ikke faktisk opprette en kontroll som vises til brukeren. Det trenger litt hjelp. Det er her det andre stykket av gjengivelsesprosessen kommer inn, a renderer.

renderer

En gjengivelse kommer til spill når du kjører programmet. Jobben til rendereren er å ta plattformens agnostiske element og forvandle det til noe visuelt å presentere til brukeren.

For eksempel, hvis du brukte en Merkelapp Kontroll i ditt delte prosjekt, under driften av søknaden din, vil Xamarin.Forms rammeverket bruke en forekomst av LabelRenderer klasse for å tegne den opprinnelige kontrollen. Hvis du begynner å lure på hvordan dette skjer fra et delt kodeprosjekt, er det et veldig godt spørsmål. Svaret er, det gjør det ikke.

La oss illustrere dette med et eksempel. Start med å åpne enten Xamarin Studio eller Visual Studio. Prosessen og konseptene er de samme for begge. Hvis du bruker Xamarin Studio, er det ingen støtte for Windows Phone-prosjekter, så du vil bare opprette tre prosjekter i løsningen. Hvis du bruker Visual Studio, vil du opprette fire prosjekter.

I Visual Studio lager du et nytt prosjekt og å velge de Mobil Apps prosjektfamilie til venstre og velg Tom App (Xamarin.Forms Portable) prosjektmal til høyre. Du kan navngi prosjektet alt du liker, men hvis du ønsker å følge med meg, bruk så navnet tilpasning, og klikket OK.

Nå, avhengig av IDE, bør du se enten tre eller fire prosjekter i løsningen. Hvis du utvider referanser mappe i din Tilpasning (bærbar) prosjekt, vil du se en forsamling referanse til Xamarin.Forms.Core. Dette er hvor alle de forskjellige elementene er definert for deg å bruke i ditt delte brukergrensesnittprosjekt. Ingenting er vanlige der.

Hvis du åpner hver av plattformspesifikke prosjekter og utvider deres referanser mapper, ser du at hver enkelt inneholder en plattformspesifikk implementering av det Xamarin.Forms-biblioteket, oppkalt Xamarin.Forms.Platform.Android, Xamarin.Forms.Platform.iOS, og Xamarin.Forms.Platform.WP8 henholdsvis.

Det er i disse forsamlingene at du finner gjengivelsene for hver av Xamarin.Forms-elementene. Nå begynner du å se utformingen av prosessen. Platformen agnostiske elementer, eller Utsikt objekter, er i delte kodeprosjektet, men alle de spesifikke gjengivelsene for elementene er i plattformspesifikke prosjekter.

Dette betyr at for hver av elementene du bruker, vil det bli to renderere laget i Xamarin Studio, og tre i Visual Studio. Nå som du ser hvordan dette er strukturert i Xamarin.Forms, er det neste logiske spørsmålet vanligvis, "Når skal jeg bruke tilpasninger?".

3. Når skal du tilpasse

Det er definitivt et stort antall egenskaper og egenskaper som er definert i Xamarin. Formelementer som kan brukes til å tilpasse den endelige kontrollen på hver av plattformene. Etter å ha sagt det skjønt, finnes ikke alle tilpasninger tilgjengelig i hver av plattformene i Xamarin.Forms. Når det er tilfelle, er det to hovedscenarier når du vil lage tilpasninger.

Det første scenariet når tilpasninger vil være nødvendig, er når du vil opprette en helt tilpasset kontroll. La oss si at du ønsket å opprette en kalenderkontroll eller kanskje en slags grafikkontroll. Dessverre eksisterer ingenting som det i dag i Xamarin.Forms, som ikke er å si at det aldri vil.

Dette er definitivt en situasjon hvor du må starte fra firkantet og lage alt fra grunnen av. Du må definere elementet du skal bruke for å beskrive egenskapene til kontrollen på en plattform agnostisk måte. Deretter må du også opprette en tilpasset renderer for hver av plattformene du ønsker å støtte.

Avhengig av hva du bygger, kan dette være et ganske omfattende prosjekt. Når det er tilfelle, vil jeg lagre det for en annen opplæring i seg selv. I stedet vil vi i denne opplæringen fokusere på det andre scenariet der du trenger litt tilpasning.

Den andre situasjonen som du finner deg selv trenger litt tilpasning er når et innebygd element ikke støtter en bestemt funksjon av en plattform du ønsker å støtte. Et eksempel på dette ville være på Merkelapp styre. I Xamarin.Forms er det ingen mekanisme eller eiendom som lar deg opprette ekvivalenten på hver av plattformene for å gjøre teksten fet eller kursiv. Dette kan virke som et veldig enkelt scenario, men du vil oppdage at den grunnleggende prosessen med å gjøre denne endringen tilgjengelig i elementet og få rendereren å forstå det, vil være det samme her som i noen av de mer komplekse scenariene.

Med det andre scenariet i tankene har du to alternativer. Du kan enten erstatte eksisterende renderer for en bestemt plattform (eller for alle plattformer) og lage din egen funksjonalitet og tegningslogikk for alle elementets evner. Alternativt kan du lage ditt eget element som kommer fra det eksisterende elementet og tilknytte det nye elementet med en tilpasset renderer. På denne måten vil du beholde alle standardlogikk- og renderingskapasitetene til basiselementet og tilpasse det som du ønsker. Dette vil være ruten vi tar for dette eksempelet. Nå, la oss se hvordan du legger til denne funksjonaliteten til vårt eget prosjekt.

4. legge til tilpasning

La oss starte denne prosessen ved å sette opp grunnstrukturen i applikasjonen vår slik at vi kan se vår grunnlinje og deretter gjøre endringer. Begynn med å åpne din App.cs fil i Tilpasning (bærbar) prosjekt i Solution Explorer. Endre GetMainPage metode for å se slik ut:

offentlig statisk side GetMainPage () var iLabel = ny etikett TextColor = Color.Black, Text = "Jeg vil bli kursiv!", HorizontalOptions = LayoutOptions.CenterAndExpand; var bLabel = ny etikett Text = "Jeg vil være modig!", TextColor = Color.Black, HorizontalOptions = LayoutOptions.CenterAndExpand; var bothLabel = ny etikett Text = "Jeg vil være kursiv og fet!", TextColor = Color.Black, HorizontalOptions = LayoutOptions.CenterAndExpand; returner nytt ContentPage BackgroundColor = Color.White, Content = ny StackLayout Padding = 100, Spacing = 100, Children = iLabel, bLabel, bothLabel; 

Som du kan se her, har vi opprettet tre enkle Merkelapp kontroller. Man ønsker å være kursiv, man ønsker å være modig, og den tredje er grådig og vil være begge. Hvis du skulle kjøre denne applikasjonen på iOS, Android og Windows Phone, ville de se slik ut:

iOS

Android

Windows telefon

Som du kan se, vil de ikke være så kjedelige. Vel, ikke bare sitte der, hjelp dem ut.

Trinn 1: Opprette et nytt element

Det første vi må gjøre er å opprette et nytt element som vi kan bruke til å gi ytterligere tilpasninger til eksisterende Merkelapp styre. Start med å legge til en ny klasse i din Tilpasning (bærbar) prosjekt og navn det StyledLabel. Erstatt innholdet med følgende:

public enum StyleType Italic, Bold, BoldItalic offentlig klasse StyledLabel: Etikett public StyleType Style get; sett; 

Vi definerer en veldig enkel opptelling og klasse. Vi har definert opptellingen for å tillate kursiv, fet og fet samt kursiv kursiv verdier. Vi lager så en klasse StyledLabelsom kommer fra Merkelappbaseklasse og legg til en ny eiendom, Stil,å holde den aktuelle stilen vi ønsker å søke om kontrollen.

For å sikre at alt fortsatt fungerer, og det skal, la oss endre App.cs filen igjen og erstatt Merkelapp elementer i vårt første eksempel med vår nye StyledLabel elementer. Fordi det StyleLabel Klassen arver fra Merkelapp klasse, alt skal fortsatt fungere.

offentlig statisk side GetMainPage () var iLabel = ny StyledLabel TextColor = Color.Black, Text = "Jeg vil bli kursiv!", HorizontalOptions = LayoutOptions.CenterAndExpand, Style = StyleType.Italic; var bLabel = ny StyledLabel Text = "Jeg vil være fet!", TextColor = Color.Black, HorizontalOptions = LayoutOptions.CenterAndExpand, Style = StyleType.Bold; var bothLabel = new StyledLabel Text = "Jeg vil være kursiv og fet!", TextColor = Color.Black, HorizontalOptions = LayoutOptions.CenterAndExpand, Style = StyleType.BoldItalic; returner nytt ContentPage BackgroundColor = Color.White, Content = ny StackLayout Padding = 100, Spacing = 100, Children = iLabel, bLabel, bothLabel; 

Igjen, her er resultatene av denne endringen.

iOS

Android

Windows telefon

Som du kan se, har ingenting blitt forandret. Nå som vi har et nytt tilpasset element, er det på tide å lage de tilpassede gjengivelsene for å ta vare på de innfødte kontrollene.

Trinn 2: Android Renderer

Det første trinnet for å lage en gjengivelse er å legge til en ny klasse på plattformen du målretter mot. Vi skal begynne med Xamarin.Android prosjekt. I dette prosjektet oppretter du en ny klassefil og heter den StyledLabelRenderer og erstatt innholdet med følgende:

bruker Android.Graphics; bruker tilpassing; bruker Customization.Droid; bruker Xamarin.Forms; bruker Xamarin.Forms.Platform.Android; [samling: ExportRenderer (typeof (StyledLabel), typeof (StyledLabelRenderer)) navneområde Customization.Droid offentlig klasse StyledLabelRenderer: LabelRenderer beskyttet overstyring ugyldig OnElementChanged (ElementChangedEventArgs

La oss se nærmere på denne kodeblokken.

[forsamling: ExportRenderer (typeof (StyledLabel), typeof (StyledLabelRenderer))]

Vi starter med en spesiell montering attributt som forteller Xamarin.Forms å bruke dette StyledLabelRenderer klasse som renderer hver gang den prøver å gjengi StyledLabel objekter. Dette kreves for at tilpassingene dine fungerer som de skal.

Akkurat som når vi opprettet en ny StyledLabel element, vi arvet fra Merkelapp klasse, vi vil ha vår nye StyledLabelRenderer klasse arve fra LabelRenderer klasse. Dette vil tillate oss å beholde eksisterende funksjonalitet, slik at vi bare må overstyre det vi vil endre eller tilpasse.

For å kunne bruke vår nye formatering, må vi hoppe inn i gjengivelsesprosessen, og det gjør vi via OnElementChanged metode. I denne metoden kan vi gjøre alle våre tilpasninger.

Når du gjør tilpassinger, er det to svært viktige egenskaper du vil bruke. Først må du få en referanse til det opprinnelige elementet du opprettet, og det blir gjort i vår tilpassede renderer-metode. Du gjør dette ved å bruke Element eiendom. Dette er et generisk objekt, så du må kaste dette til hvilken type du gjengir. I dette tilfellet er det a StyledLabel.

var styledLabel = (StyledLabel) Element;

Den andre viktige eiendommen du trenger er den Styre eiendom. Denne egenskapen inneholder en skrevet referanse til den opprinnelige kontrollen på plattformen. I dette tilfellet, siden du har arvet fra LabelRenderer klasse, koden vet allerede at Styre i dette tilfellet er en TextView.

Fra dette punktet vil du bruke noen enkle logikk for å bestemme hvilken tilpasning som skal utføres og anvende de aktuelle innfødte tilpasningene. I dette tilfellet vil du bruke Android-mekanismen for å endre skrifttypen til a TextView ved å bruke SetTypeface metode.

bytt (styledLabel.Style) case StyleType.Bold: Control.SetTypeface (null, TypefaceStyle.Bold); gå i stykker; case StyleType.Italic: Control.SetTypeface (null, TypefaceStyle.Italic); gå i stykker; case StyleType.BoldItalic: Control.SetTypeface (null, TypefaceStyle.BoldItalian); gå i stykker; 

Hvis du skulle kjøre denne applikasjonen nå, bør du se noe som følger i Android-emulatoren, som er akkurat det vi målte for.

Trinn 3: IOS Renderer

Prosessen med å opprette iOS-gjengivelsen er nøyaktig den samme opp til poenget med å overstyre OnElementChanged metode. Begynn med å opprette en ny klasse i din Customization.iOS prosjekt. Navngi det StyledLabelRenderer og erstatt innholdet med følgende:

bruker tilpassing; bruker Customization.iOS; bruker MonoTouch.UIKit; bruker Xamarin.Forms; bruker Xamarin.Forms.Platform.iOS; [samling: ExportRenderer (typeof (StyledLabel), typeof (StyledLabelRenderer)) navneområde Customization.iOS offentlig klasse StyledLabelRenderer: LabelRenderer beskyttet overstyring ugyldig OnElementChanged (ElementChangedEventArgs

Som du kan se, er alt akkurat det samme. Du har det samme montering attributt, du overstyrer det samme OnElementChanged Metoden du støper på Element eiendom til a StyledLabel, og du har samme skall av a bytte om uttalelse om å arbeide gjennom Stil eiendom.

Den eneste forskjellen kommer inn der du bruker stylingen til den innfødte UILabel styre.

bytt (styledLabel.Style) case StyleType.Bold: Control.Font = UIFont.BoldSystemFontOfSize (16.0f); gå i stykker; case StyleType.Italic: Control.Font = UIFont.ItalicSystemFontOfSize (16.0f); gå i stykker; case StyleType.BoldItalic: Control.Font = UIFont.FromName ("Helvetica-BoldOblique", 16.0f); gå i stykker; 

Måten du lager en UILabel's Font Egenskapen enten fet eller kursiv i iOS er gjennom en statisk hjelpemetode på UIFont klassen heter enten BoldSystemFontOfSize eller ItalicSystemFontOfSize. Det vil fungere i tilfelle enten en fet skrift eller en kursiv skrift, men ikke begge. Hvis du prøver å bruke begge disse til en UILabel, bare den siste vil gjengi.

For å få begge stilene, vil vi jukse litt og bruke en innebygd skrift i iOS-navnet Helvetica-BoldOblique. Denne skrifttypen har både fet og kursiv innebygd, slik at vi ikke trenger å gjøre dem individuelt.

Kjører dette i iOS-simulatoren gir deg følgende resultat:

Trinn 4: Windows Phone Renderer

Endelig kommer vi til Windows Phone. Som du kanskje allerede har gjettet, er prosessen akkurat den samme. Opprett en ny klasse i Customization.WinPhone prosjekt, nevner det StyledLabelRenderer og erstatt innholdet med følgende:

bruker System.Windows; bruker tilpassing; bruker Customization.WinPhone; bruker Xamarin.Forms; bruker Xamarin.Forms.Platform.WinPhone; [samling: ExportRenderer (typeof (StyledLabel), typeof (StyledLabelRenderer)) navneområde Customization.WinPhone offentlig klasse StyledLabelRenderer: LabelRenderer beskyttet overstyring ugyldig OnElementChanged (ElementChangedEventArgs

Igjen er alt det samme med unntak av logikken. I dette tilfellet, for å gjøre kursiv kursiv, setter du inn TextBlock's Fontstil eiendom til kursiv. Så for å gjøre teksten fet, setter du inn FontWeight eiendom til Modig. Hvis du ønsker å søke begge, setter du rett og slett begge.

Kjører denne applikasjonen i Windows Phone emulatoren vil gi deg følgende resultat:

Du har nå opprettet et fullt funksjonelt, tilpasset, kryssplattformelement som gjør seg perfekt på alle tre plattformene. Du burde nå føle deg klar til å ta på verden. Vel, nesten.

Prosessen som vi har fulgt gjennom denne opplæringen er helt gyldig og i de fleste tilfeller kommer til å fungere perfekt. Det er imidlertid et veldig spesifikt tilfelle, der vi vil gå glipp av noen funksjonalitet hvis vi bruker denne tilnærmingen. Det saken er data-bindende i XAML.

5. XAML og data-binding

En av de veldig kul funksjonene til Xamarin.Forms er det faktum at du får bruke XAML og data-binding, akkurat som du ville hvis du opprettet en Windows Phone, WPF eller Silverlight-applikasjon. Dessverre databindende og XAML er utenfor omfanget av denne opplæringen, men jeg oppfordrer deg til å lese mer om dette emnet på XAML for Xamarin.Forms-siden.

Trinn 1: Bygg XAML-siden

La oss starte med å bygge en enkel XAML-side som dupliserer brukergrensesnittet vi tidligere har opprettet i kode. Start med å legge til en ny fil til din Tilpasninger (Bærbar) prosjekt, velg Skjemaer XAML Side filtype og gi den navnet StyledLabelPage.

Når filen er opprettet, erstatt innholdet med følgende:

       

Denne XAML vil opprette nøyaktig samme side som vi har jobbet med før. Legg merke til tillegg av xmlns: lokale navneområdedeklarasjon øverst på filen, i tillegg til lokale: prefiks før hver referanse til StyledLabel objekter. Uten disse vil XAML-parseren ikke vite hva a StyledLabel er og til slutt vil ikke kunne kjøre.

For å kjøre dette må du lage to små endringer. Først åpner du App.cs fil og endre GetMainPage metode for å se slik ut:

offentlig statisk side GetMainPage () returner ny StyledLabelPage (); 

For det andre, åpne StyledLabelPage.xaml.cs fil og endre den for å se slik ut:

offentlig delklasse ClassedLabelPage: ContentPage offentlig StyledLabelPage () InitializeComponent (); 

Nå, når du kjører programmene dine, bør du få de samme resultatene på alle tre plattformene. Ganske pent, huh?

iOS

Android

Windows telefon

Trinn 2: Legge til data-binding

Hvis du er kjent med konseptet med Model View View-Model mønsteret (MVVM), vil du vite at en av sine primære egenskaper er data-bindende. Faktisk var dette mønsteret utformet rundt bruk av XAML.

Data-binding er prosessen med å tillate at egenskapene til to objekter kobles sammen slik at en endring i en vil skape en forandring i den andre. Prosessen med data-binding innenfor XAML oppnås ved bruk av Binding Markup Extension

Markup utvidelser er ikke en funksjon av Xamarin.Forms, eller til og med av XAML. Det er faktisk en funksjon av XML som tillater ekstra funksjonalitet å bli brukt på prosessen med å sette verdien av et attributt i et element.

For eksempel, la oss se nærmere på den første StyledLabel element i eksempelet ovenfor.

 

Problemet med denne markeringen er at alle egenskapene (attributter) blir eksplisitt tilordnet. Dette skaper en ganske ubøyelig design. Så hva skjer hvis en eller annen grunn under gjennomføringen av vår søknad, vil vi endre Stil attributt til å ha en verdi på Modig? Vel, i vår kode-bak-fil, må vi se etter en hendelse, ta den hendelsen, ta tak i denne forekomsten av StyledLabel element og endre denne attributtverdien. Det høres ut som mye arbeid. Ville det ikke vært fint om vi kunne gjøre prosessen enklere? Vel, det kan vi.

Binding Markup Extension

Måten du kan gjøre dette designet mer fleksibelt for modifikasjon, er gjennom bruk av binding markup forlengelse. Slik bruker du denne utvidelsen, er ved å endre merkingen slik at den ser ut som følgende:

 

Som du kan se, har vi endret verdien av Stil eiendom til Binding FirstStyle. Bruken av en markupforlengelse er typisk signifisert ved bruk av krøllete braces . Dette betyr at det som finnes inne i de krøllete båndene skal bli en markup forlengelse.

I dette tilfellet bruker vi binding forlengelse. Den andre delen av denne utvidelsen er navnet på en eiendom som vi vil binde til denne egenskapen (attributt). I dette tilfellet vil vi kalle det FirstStyle. Det eksisterer ikke ennå, men vi skal ta vare på det i et øyeblikk. Først, la oss fullstendig oppdatere denne filen for å dra nytte av datainnbinding.

       

BindingContext

Siden vi oppretter en binding, forsøker vi å knytte dette XAML-attributtet til noe annet som gjør at disse to egenskapene kan dele sine data. For å gjøre det må du først opprette en klasse som inneholder egenskaper med de samme navnene som vi bruker i XAML-eksemplet ovenfor.

Opprett en ny klasse i Tilpasninger (Bærbar) prosjekt og navn det SampleStyles og erstatt innholdet med følgende:

offentlig klasse SampleStyles public StyleType FirstStyle get; sett;  offentlig StyleType SecondStyle get; sett;  offentlig StyleType ThirdStyle get; sett; 

Dette er en veldig enkel klasse som inneholder tre egenskaper av typen StyleType med de samme navnene som vi brukte i vår binding av attributter. Vi har nå XAML ved hjelp av binding markup forlengelse og en klasse som inneholder egenskaper med samme navn som vi ser i bindingene i XAML. Vi trenger bare lim for å sette dem sammen. Det limet er BindingContext.

For å koble egenskapene til disse objektene sammen, må vi tilordne en forekomst av SampleStyles klasse til BindingContext tilhører StyledLabelPage. Åpne StyledLabelPage.xaml.cs filen og endre konstruktøren slik at den ser ut som følgende:

offentlig StyledLabelPage () InitializeComponent (); BindingContext = nye sampleStyles FirstStyle = StyleType.Italic, SecondStyle = StyleType.Bold, ThirdStyle = StyleType.BoldItalic; 

I teorien, hvis du skulle kjøre din søknad, vil XAML-filen bli fylt med verdiene fra vår SampleStyles egenskaper og alt ville bli gjengitt på skjermen som vi så før. Dessverre er det ikke tilfelle. Du avslutter å få et unntak ved kjøretid som ser slik ut:

Hvis du ser på Tilleggsinformasjon, du vil se problemet er det Ingen Egenskap av navn Stil funnet. Dette er et resultat av måten vi opprettet StyledLabel i begynnelsen. For å utnytte databindingen må egenskapene dine være av typen BindableProperty. For å gjøre dette, må vi gjøre en liten modifikasjon til vår StyledLabel klasse.

offentlig klasse StyledLabel: Etikett public static readonly BindableProperty StyleProperty = BindableProperty.Create(p => p.Style, StyleType.None); offentlig StyleType Style get return (StyleType) base.GetValue (StyleProperty);  sett base.SetValue (StyleProperty, verdi);

Som du kan se, har vi lagt til en statisk eiendom som heter StyleProperty av type BindableProperty. Vi tilordnet det resultatet av en CreateMethod som definerer eieren av eiendommen vi jobber med.

Eiendommen er Stil, men eieren er StyledLabel. Den andre generiske parameteren er tilbaketype av eiendommen, som er en StyleType. Da er det eneste argumentet vi leverer til metoden et uttrykk som definerer hva som blir returnert og en standardverdi. I vårt tilfelle returnerer vi verdien av Stil forekomst eiendom og standard vil være Ingen, eller ingen styling.

Vi må da modifisere Stil eiendomsimplementering for å utsette funksjonen for å få og sette inn i grunnklassen slik at BindingProperty oppdateres riktig hvis verdien av Stil eiendomsendringer.

Nå, hvis du skulle kjøre din søknad igjen, bør du se at alt fungerer som forventet.

iOS

Android

 

Windows telefon

Konklusjon

I denne opplæringen lærte du om et veldig viktig konsept i verden av Xamarin.Forms, customization. Tilpasning er en av de viktigste funksjonene som gjør at de kan skille seg ut fra konkurransen.

Å vite hvordan, når og hvor å tilpasse er en svært viktig ferdighet å ha som mobilutvikler. Jeg håper du finner disse ferdighetene nyttige og kan sette dem til nytte i ditt neste prosjekt.