- Flutter i Jetpack Compose dijele deklarativni, reaktivni UI model, ali se razlikuju po jeziku, ekosistemu i dosegu platforme.
- Compose jasno mapira na Flutter koncepte: composable elemente na widgete, Lazy liste na ListView/GridView, Canvas na CustomPainter i teme na ThemeData.
- Android vještine (životni ciklus, navigacija, resursi, konkurentnost) se direktno prenose na Flutter putem widgeta, Navigatora, resursa i async/await.
- Za projekte samo za Android, Compose je odličan izbor, dok se Flutter ističe kada vam je potrebna jedna kodna baza za Android, iOS, web i desktop.
Ako se već osjećate kao kod kuće pišući korisničke interfejse pomoću Jetpack Compose-a i pitate se koliko je teško preći na Flutter, u odličnoj ste poziciji. Oba alata su deklarativna, reaktivna i izradio ih je Google, tako da se veliki dio vašeg mentalnog modela prenosi gotovo u potpunosti. Glavne razlike leže u jeziku (Kotlin vs Dart), strukturi projekta i načinu na koji svaki okvir komunicira s temeljnim slojevima Androida (a u slučaju Fluttera, iOS-a, weba i desktopa).
Ovaj vodič je napisan posebno za Jetpack Compose developere koji žele detaljno razumjeti Flutter, bez marketinških nepotrebnih elemenata. Vidjet ćete kako se osnovni koncepti preslikavaju između dva svijeta: kompozitni elementi naspram widgeta, modifikatori naspram parametara konstruktora, lijeni rasporedi naspram ListView/GridViewa, Canvas naspram CustomPaintera, navigacija Compose naspram Navigatora, remember naspram StatefulWidgeta i još mnogo toga. Također ćemo povezati vaše šire znanje o Androidu (Views, životni ciklus, resursi, namjere, rad u pozadini) s njihovim Flutter ekvivalentima tako da će krivulja učenja više djelovati kao bočni korak nego kao uspon.
Od Jetpack Composea do Fluttera: gdje se vaše vještine prenose
Flutter je Googleov UI okvir za izradu višeplatformskih aplikacija koristeći Dart jezik, dok je Jetpack Compose Googleov moderni UI alat za izvorni Android koristeći Kotlin. U suštini, oni ciljaju na različita okruženja za izvršavanje, ali arhitektonski dijele istu veliku ideju: opisati korisnički interfejs kao funkciju stanja, pustiti okvir da shvati kada i kako da ponovo iscrta.
U Jetpack Compose-u razmišljate u smislu kompozibilnih funkcija, modifikatora i rekompozicije; u Flutter-u razmišljate u smislu widgeta, parametara konstruktora i ponovnih izgradnja. Uprkos različitom imenovanju, ponašanje je zapanjujuće slično: gradite stablo UI elemenata, svaki čvor je nepromjenjiv, a kada se stanje promijeni, okvir ponovo prolazi kroz to stablo kako bi proizveo ažurirani interfejs.
Jedna ključna razlika je to što je Flutter po dizajnu višeplatformski. Ista Dart kodna baza može ciljati Android, iOS, web, Windows, macOS i Linux. Compose se širi izvan Androida (na primjer sa Compose Multiplatform), ali Flutterova priča o više uređaja je trenutno mnogo zrelija i kohezivnija, što je upravo razlog zašto mnogi Android timovi razmatraju ovu opciju kada žele isporučiti aplikaciju za iOS ili desktop računare.
Vaše razumijevanje same Android platforme je i dalje izuzetno vrijedno u Flutter projektima. Dok je UI sloj čisti Dart i widgeti, Flutter se oslanja na Android (i iOS) za dozvole, konfiguraciju sistema, API-je platforme, obavještenja, rad u pozadini i mnoge druge mogućnosti, kojima se pristupa putem dodataka i kanala platforme. To znači da sva intuicija koju ste stekli o tome kako se Android ponaša ne propada - on se samo pomiče jedan sloj niže.
Deklarativni UI model: kompozitni elementi naspram widgeta
I Jetpack Compose i Flutter implementiraju deklarativni UI model: opisujete „kako“ bi UI trebao izgledati za dato stanje, a ne „kako“ mutirati prikaze korak po korak. Umjesto pozivanja settera na prikazima, ponovo gradite svoje stablo kada se stanje promijeni i omogućavate okviru da efikasno vrši razlike i ponovo crta.
U Jetpack Compose-u, UI elementi su kompozitne funkcije označene sa @Composable, često konfiguriran sa Modifier. Dugme bi moglo biti Button(onClick = ..., modifier = Modifier.padding(16.dp))Lanac modifikatora ukrašava ili postavlja kompozibilni element bez promjene njegovog osnovnog tipa, a Compose koristi rekompoziciju za osvježavanje samo dijelova stabla čiji su se ulazi promijenili.
U Flutteru, UI elementi su vidžeti - obični Dart objekti koji opisuju konfiguraciju. Također su nepromjenjivi i raspoređeni u stablu, ali umjesto prosljeđivanja modifikatora, obično se argumenti rasporeda ili stiliziranja prosljeđuju direktno putem parametara konstruktora ili se widget umotava u druge widgete rasporeda. Na primjer, mogli biste napisati Padding(padding: EdgeInsets.all(16), child: ElevatedButton(...)) da se postigne sličan rezultat.
Životni ciklus i kompozitnih elemenata i widgeta je namjerno kratak i nepromjenjiv. Oni žive samo dok novi unos ne zahtijeva njihovu zamjenu; nijedan ne pokušava upravljati vlastitim životnim vijekom niti se direktno mijenjati. To je konceptualni pomak u odnosu na stari svijet Android Viewa gdje su prikazi dugovječni objekti, ponovo korišteni i mutirani tokom vremena, i zato vaš Compose način razmišljanja djeluje tako prirodno u Flutteru.
U suštini, raspored u oba okvira prati isti obrazac vođen od strane roditelja i zasnovan na ograničenjima. Roditelj mjeri sebe, prenosi ograničenja, potomci biraju veličinu poštujući ta ograničenja, a roditelj pozicionira svoju djecu. U Flutteru ćete ovo vidjeti direktno prikazano kao BoxConstraints; u Compose-u se to rješava u implementacijama MeasurePolicy. U oba slučaja, roditelji mogu ograničiti djecu - vidžeti ne mogu jednostavno odabrati bilo koju veličinu ili položaj koji žele.
Strukturiranje aplikacije: ulazna tačka, scaffolding i rasporedi
Na Androidu sa Compose-om, vaša ulazna tačka je obično Activity (često ComponentActivity) gdje zovete setContent za hostovanje vaših kompozitnih elemenata. Odatle gradite kompozibilno stablo, obično počevši sa MaterialTheme i površinu ili skelu koja definira vaš raspored na visokom nivou.
U Flutteru, ulazna tačka je Dart. main funkcija koja poziva runApp sa korijenskim vidžetom vaše aplikacije. Taj korijen je obično MaterialApp or WidgetsApp dodatak, koji postavlja usmjeravanje, teme, lokalizaciju i osnovni navigator. Prvi "ekran" koji prikažete često koristi Scaffold vidžet, koji igra ulogu vrlo sličnu Scaffold U Material 3 Compose: pruža vam traku aplikacija, tijelo, plutajuće dugme za akciju, ladice i tako dalje.
Za jednostavan tekst i statički sadržaj, Compose bi mogao podrazumijevano prelomiti sadržaj - usklađujući veličinu sa suštinskim sadržajem - dok mnogi Flutter widgeti podrazumijevano zauzimaju više dostupnog prostora osim ako nije ograničen. Na primjer, ako postavite Text kompozibilan unutar kolone, neće automatski popuniti širinu. U Flutteru, Text unutar a Column može se ponašati različito ovisno o ograničenjima roditelja. Da biste centrirali sadržaj u Flutteru, često ćete ga umotavati u Center widget ili koristite widgete za raspored kao što je Align, Row, Column, I Expanded u kombinaciji sa svojstvima poravnanja.
Linearni rasporedi se mapiraju gotovo savršeno: Compose ima Row i Column, kao i Flutter. U Flutteru prenosite djecu kao List<Widget> i kontrolišite razmak i poravnanje pomoću svojstava kao što su MainAxisAlignment i CrossAxisAlignmentU Composeu se oslanjate na horizontalArrangement, verticalArrangement, horizontalAlignment i verticalAlignmentKoristan način razmišljanja o tome: svojstva koja završavaju na „Arrangement“ (Raspored) preslikavaju se na glavnu os Fluttera, a ona koja završavaju na „Alignment“ (Poravnanje) preslikavaju se na poprečnu os.
Kada su vam potrebni relativni ili preklapajući rasporedi, pristupi su također konceptualno usklađeni. U Android XML-u biste mogli posegnuti za RelativeLayout ili ugniježđenu mješavinu LinearLayout i FrameLayoutU Compose-u biste pisali Row, Column i Box (ili napišite prilagođeni raspored). U Flutteru je analogno Row, Column i Stack u kombinaciji s pozicioniranom djecom i opcijama poravnanja. Vaš mentalni model za međusobno raspoređivanje elemenata se kreće gotovo nepromijenjen.
Dugmad, unos i interakcija
U Jetpack Compose-u, kreiranje dugmeta obično znači korištenje Button ili jednu od njegovih Material varijanti, koja se pod Material 3 rješava specifičnom implementacijom kao što je FilledTonalButton. Vi pružate onClick lambda i opcionalno stiliziranje, često putem parametara kao što su colors ili modifikatori za padding, širinu i poravnanje.
U Flutteru, ekvivalent je korištenje widgeta poput FilledButton, ElevatedButton, TextButton or OutlinedButton. Svaki uzima onPressed povratni poziv i child vidžet – najčešće TextMožete ih prilagoditi prosljeđivanjem style preko ButtonStyle ili korištenjem globalnog preklapanja teme, koje vam omogućava centralno podešavanje boje, oblika, elevacije i veličine za cijelu porodicu dugmadi.
Za rukovanje gestama, Compose se oslanja na modifikatore poput Modifier.clickable u mnogim slučajevima, ali možete se prebaciti i na specijalizirane detektore gestikulacije kada je to potrebno. Dugi pritisci, povlačenja i prilagođeni gestovi se obično sastavljaju putem namjenskih API-ja za modifikacije i izvora interakcije.
Flutter otkriva eksplicitnu GestureDetector vidžet koji omotate oko bilo čega što nema ugrađenu podršku za geste. Nudi širok spektar povratnih poziva: onTap, onDoubleTap, onLongPress, onVerticalDragStart, onVerticalDragUpdate, onHorizontalDragEnd i mnogi drugi. Widgeti poput ElevatedButton već izložiti onPressed svojstvo, ali za potpuno prilagođene UI elemente možete koristiti GestureDetector ili widgete višeg nivoa kao što su InkWell za povratnu informaciju o valovitosti materijala.
Unos teksta u Flutteru se upravlja pomoću TextField or TextFormField, čiji stil podsjeća na Composeov TextField i OutlinedTextField kompozitnih materijala. Nagovještaje, oznake, greške i okvire konfigurirate pomoću InputDecoration slično kao što ti koristiš TextFieldDefaults ili parametre na poljima za tekst u Composeu. Kao i u Composeu, obično reaktivno prikazujete poruke o grešci promjenom stanja i ponovnim izgradnjom dekoracije, umjesto ručnim manipulisanjem prikazima.
Liste, mreže i sadržaj koji se može pomicati
Jetpack Compose nudi dvije glavne strategije za liste: jednostavne Column/Row s iteracijom za male kolekcije i LazyColumn/LazyRow/LazyVerticalGrid/LazyHorizontalGrid za velike ili dinamičke liste. Lijeni kontejneri sastavljaju samo ono što je vidljivo, što održava visoke performanse pri radu s hiljadama stavki.
Flutter slijedi isti pristup "mali naspram velikih", ali s različitim widgetima. Za malu listu koja stane na ekran, možete koristiti samo Column i mapirajte svoje podatke na childrenZa sve što se pomiče, posežete za ListView or GridView, s konstruktorima za izradu koji lijeno kreiraju djecu samo kada je to potrebno.
Uobičajeni obrazac u Flutteru je ListView.builder, što odražava DSL stavki lijenog popisa u Composeu. Vi isporučujete itemCount i itemBuilder povratni poziv; Flutter poziva taj builder s indeksom od 0 do itemCount - 1 kad god se pojavi nova stavka. Unutar alata za izradu možete vratiti gotovo bilo koji widget - od jednostavnog ListTile s tekstom i ikonom do složenih, prilagođenih redova liste.
Za mreže, Compose-ov LazyVerticalGrid i LazyHorizontalGrid mapa do Flutter-a GridView widget. Umjesto direktnog prosljeđivanja broja kolona u mrežu, Flutter često koristi delegata kao što je SliverGridDelegateWithFixedCrossAxisCount or SliverGridDelegateWithMaxCrossAxisExtent za kontrolu rasporeda ćelija. Ovi delegati obuhvataju pravila poput "broja kolona" ili "maksimalne širine ćelije", slično po duhu parametrima veličine mreže koje koristite u Compose-u.
Ponašanje skrolovanja je također analogno u oba kompleta alata. Composeove "lijene" liste dolaze s ugrađenim skrolovanjem; ne umotavate ih u dodatne kontejnere za skrolovanje. U Flutteru, mnogi widgeti za liste i mreže su sami po sebi skrolovajući, ali za pojedinačni, neponavljajući sadržaj koji bi se trebao skrolovati možete koristiti SingleChildScrollViewIzrada prilagođenih stranica sa mogućnošću skrolovanja tada postaje stvar ugniježđivanja ili sastavljanja sliverova za naprednije slučajeve upotrebe.
Adaptivni i responzivni UI obrasci
Compose vam nudi nekoliko strategija za responzivni dizajn: prilagođene rasporede, BoxWithConstraints, WindowSizeClass i adaptivnu biblioteku Material 3. Ovo vam omogućava da promijenite kompoziciju na osnovu dostupnog prostora, položaja i kategorije uređaja, a možete ih i kombinovati u zavisnosti od složenosti projekta.
Flutter ne pokušava direktno kopirati te API-je, ali osnovna ideja je ista: pregledati ograničenja i karakteristike ekrana, a zatim granati svoj raspored. Dva glavna alata su LayoutBuilder i MediaQuery. LayoutBuilder propusnice BoxConstraints prema dolje kako biste mogli mijenjati ili preuređivati widgete iznad određenih širina ili visina. MediaQuery otkriva veličinu ekrana, orijentaciju, padding i gustoću piksela za prelomne tačke visokog nivoa.
Umjesto ciljanja na jednoznačno preslikavanje između Composeovih adaptivnih rješenja i Flutterovih, efikasnije je razmišljati u smislu vlastitih dizajnerskih zahtjeva. Kada znate kako bi se vaš korisnički interfejs trebao prilagođavati telefonima, tabletima i desktop računarima, tu logiku možete izraziti putem Compose-a. WindowSizeClass i adaptivni rasporedi ili Flutterovo grananje vođeno ograničenjima i medijima. Isto dizajnersko razmišljanje - različiti API-ji.
Upravljanje stanjem: zapamtite u odnosu na StatefulWidget i dalje
Jetpack Compose pohranjuje kratkotrajno stanje korisničkog interfejsa koristeći remember i državni nosioci poput mutableStateOf, često u kombinaciji sa ViewModel i arhitektonske komponente za duže trajanje stanja. Kada se stanje promijeni, dolazi do rekompozicije i relevantni kompozitni elementi dobijaju nove vrijednosti.
Flutterova priča o stanju niskog nivoa vrti se oko StatefulWidget i s njim povezane State objekat. Definišete widget koji želi da zadrži stanje proširivanjem StatefulWidget, a zatim implementirajte zaseban State<MyWidget> klasa za pohranjivanje promjenjivih polja. Kad god ažurirate ta polja, pozivate setState(), što označava taj dio stabla widgeta kao prljav i pokreće ponovnu izgradnju. Na ovom nivou je vrlo slično pohranjivanju stanja sastavljanja sa remember i poništavanje kompozitnih elemenata kada se vrijednosti promijene.
Za složenije aplikacije, Flutter se uveliko oslanja na obrasce zajednice i prve strane: Provider, Riverpod, Bloc, prodavnice u stilu Reduxa i još mnogo toga. Oni djeluju kao analozi vaših Android arhitektonskih stekova: ViewModel + LiveData/Flow + repozitoriji u Compose projektima. Oni centraliziraju poslovnu logiku i otkrivaju reaktivne tokove podataka koji pokreću ponovnu izgradnju widgeta. Iz Compose pozadine, mnogi od ovih obrazaca će vam biti poznati čak i ako se API-ji razlikuju.
Jedna stvar koja često iznenađuje Android developere je da se i vidžeti sa i bez stanja u Flutteru često obnavljaju - potencijalno svaki kadar tokom animacija. Razlika nije u učestalosti ponovne izgradnje, već u tome gdje se pohranjuje promjenjivo stanje: StatefulWidget pruža ti pratioca State objekt koji preživi ponovne izgradnje, slično kao što remember omogućava vrijednostima da prežive rekompoziciju u Compose-u.
Crtanje, animacija i vizualno dotjerivanje
Ako ste ikada direktno radili sa Android uređajima Canvas i Drawable, Compose-ov Canvas composable se vjerovatno činio jednostavnim. Pruža deklarativni način crtanja oblika, slika i teksta u Kotlinu, skrivajući mnogo imperativne ceremonije tradicionalnih prilagođenih prikaza.
Flutter otkriva sličnu površinu za crtanje kroz Canvas API, pristupljeno putem CustomPaint i CustomPainter. Vi implementirate CustomPainter klasa u kojoj prepisujete paint metoda crtanja na platnu pomoću Paint objekte, putanje, transformacije i tako dalje. Zatim taj alat za slikanje pridružujete CustomPaint widget. I Compose i Flutter se oslanjaju na Skia engine, tako da primitivi - linije, putanje, shaderi - izgledaju vrlo poznato iz Androidovog 2D renderiranja.
Za animacije, Flutter se oslanja na eksplicitni sistem animacije izgrađen oko AnimationController, Animation<T> i Tweens, plus bogat skup animiranih widgeta. Kreirate instancu kontrolera (obično sa SingleTickerProviderStateMixin za vsync), definirajte CurvedAnimations ili Tweens koji mapiraju napredak od 0 do 1 u vrijednosti domena, a zatim ih povežite s widgetima poput FadeTransition, ScaleTransition, AnimatedBuilder ili implicitne widgete kao što su AnimatedContainerSistem animacije također otkriva AnimationStatus povratne funkcije koje reaguju na početak, završetak ili poništavanje.
Jetpack Compose-ovi API-ji za animaciju su deklarativni od vrha do dna, sa funkcijama kao što su animate*AsState, prijelazi i animirana vidljivost. Umjesto ručnog upravljanja kontrolerima u većini uobičajenih slučajeva, opisujete ciljna stanja, a okvir upravlja interpolacijom tokom vremena. Kada vam je potrebna više prilagođene kontrole, i dalje imate pristup primitivima niskog nivoa, ali uobičajeni put je koncizniji od klasičnog Android XML-a ili imperativnog animacijskog koda.
Konceptualno, oba seta alata koristite na isti način: widgeti/kompozitni elementi moraju biti lagani i čisti, kroz njih se propuštaju vremenski promjenjive vrijednosti, a okvir se mora baviti interpolacijom i poništavanjem. Kao Compose developer, dodatna eksplicitnost Flutterovog AnimationController Možda se u početku čini pomalo staromodno, ali vam pruža vrlo preciznu kontrolu nad vremenom, krivuljama i orkestracijom.
Stiliziranje, teme, fontovi i resursi
Moderne aplikacije žive ili umiru od uglađenosti, tako da i Flutter i Compose stavljaju veliki naglasak na teme i stiliziranje. Sastavite upotrebu MaterialTheme sa shemama boja, tipografijom i definicijama oblika, a možete ugnijezditi teme kako biste nadjačali vrijednosti za podstabla - uključujući forsiranje svijetlih ili tamnih površina za određene regije.
U Flutteru, ekvivalent je ThemeData prošao MaterialApp or Theme dodaci. Definišete primarne boje, osvetljenost, tipografiju i teme specifične za komponente, kao što su elevatedButtonTheme, textButtonTheme, appBarTheme i više. Teme možete lokalno prepisati tako što ćete podstabla umotati u Theme vidžeti koji kopiraju roditeljski element i podešavaju određena polja. Svijetli i tamni način rada mogu se prebacivati na nivou aplikacije pružanjem theme i darkTheme i kontrolu themeMode.
Stiliziranje teksta je poznata teritorija: u Compose-u ili direktno prosljeđujete jednostavna svojstva u Text ili dostaviti TextStyle objekat. Flutter ovo odražava sa Text vidžet koji prihvata TextStyle preko svog style parametar. TextStyle Pokriva porodicu fontova, veličinu, debljinu, razmak između slova, visinu reda, dekoraciju i još mnogo toga. Možete definirati globalne tekstualne teme u ThemeData.textTheme i referencirajte ih svugdje, baš kao što biste koristili tipografiju iz MaterialTheme u Composeu.
Fontovi i slike se obrađuju putem resursa, a ne tradicionalno na Androidov način. /res stablo direktorija. Flutter ne nameće određeni raspored foldera; deklarišete resurse u pubspec.yaml a zatim ih referencirati iz koda. Slike se obično učitavaju sa Image.asset(), što se rješava u ispravnu gustoću na osnovu devicePixelRatioLogički pikseli igraju istu ulogu kao dp na Androidu, apstrahujući fizičku gustinu piksela.
Za prilagođene fontove, Compose vam omogućava da ili pakujete resurse fonta ili ih preuzmete tokom izvođenja putem provajdera poput Google Fonts-a, a zatim ih povežete sa FontFamily i tipografija. Flutter koristi gotovo isti obrazac: datoteke fontova stavlja u mapu resursa, navodi ih u pubspec.yaml, a zatim referencirajte porodicu fontova po imenu u TextStyleAko želite fontove koji se preuzimaju tokom izvođenja programa, postoji popularan google_fonts dodatak koji otkriva Dart funkcije nazvane po fontovima - npr. GoogleFonts.robotoTextTheme()—da ih brzo povežete sa svojom temom.
Oba ekosistema tretiraju stringove i lokalizaciju kao prvorazredne probleme, iako Flutter nema direktan ekvivalent Androidovim XML string resursima. Umjesto toga, najbolja praksa je zadržati prevode u .arb datoteke i povezati ih s Flutter alatima za lokalizaciju. Pristup se zatim odvija putem generiranih Dart klasa, otprilike analogno korištenju R.string identifikatori u Android kodu.
Koncepti Android platforme kroz Flutter prizmu
Pored korisničkog interfejsa, jedno od najvećih pitanja koje Compose programeri imaju je kako se njihovo znanje o Androidu preslikava na Flutterovu arhitekturu. Srećom, mnoge od osnovnih ideja - aktivnosti, životni ciklus, namjere, pozadinski rad, resursi, umrežavanje - imaju jasne ekvivalente, čak i ako površinski API izgleda drugačije.
U Androidu, Activity i Fragment su vaši primarni ekrani i kontejneri; u Flutteru je sve widget, a navigacija se odvija putem Navigator i Route objekata. Ruta otprilike odgovara aktivnosti ili fragmentu, ali obično postoji samo jedno mjesto za hosting. Activity na Androidu koji ugrađuje Flutter engine. Rute se postavljaju i izbacuju na Navigatorov stek, bilo putem imenovanih ruta definiranih u MaterialApp ili putem direktno izgrađenog PageRoute slučajevi poput MaterialPageRoute.
Životni ciklus povratnih poziva za Android (onCreate, onStart, onResumeitd.) nemaju jedan-na-jedan hooks u Flutter kodu, ali možete pratiti životni ciklus aplikacije pomoću WidgetsBindingObserver. To otkriva države poput resumed, inactive, paused i detached, što otprilike odgovara Androidovim fazama vidljivosti, pozadine i uništenja. Kada vam zaista trebaju niskonivojske hook-ove životnog ciklusa za upravljanje resursima, obično ih implementirate na izvornoj Android strani u FlutterActivity ili dodatak, ne u Dartu.
Namjere igraju dvije uloge na Androidu: navigacija unutar aplikacije i komunikacija između aplikacija. Kao što je spomenuto, Flutter nema API za navigaciju zasnovan na namjerama - Navigator ga u potpunosti zamjenjuje unutar Darta. Za zadatke koji se odvijaju između aplikacija (pokretanje kamere, odabir datoteka, rukovanje namjerama dijeljenja), obično se koriste dodaci (plugins) koji obuhvataju potrebne Android (i iOS) pozive. Ako ne postoji dodatak, možete napisati svoj vlastiti koristeći MethodChannels za komunikaciju između Darta i izvornog koda, prosljeđujući namjere i rezultate kao poruke.
Vaše razumijevanje rada u pozadini i niti se također prenosi, ali primitivi izgledaju drugačije. Android vas podstiče da premjestite mrežne i diskovne I/O operacije izvan glavne niti koristeći korutine, AsyncTask (zastarjeli), WorkManager, JobScheduler, RxJava i tako dalje. Dart, nasuprot tome, koristi petlju događaja s jednom niti po izolatu, s async/await za I/O operacije i odvojenim izolatima za rad koji zahtijeva puno CPU-a. Za sve što je vezano za I/O operacije, samo označite svoje funkcije. async, await operaciju i pustite da petlja događaja održava korisnički interfejs responzivnim; za zahtjevne CPU zadatke pokrećete izolat i komunicirate putem prosljeđivanja poruka umjesto dijeljene memorije.
Što se tiče umrežavanja, Flutter je popularan http Paket igra ulogu sličnu OkHttp + Retrofit za osnovne slučajeve upotrebe. Skriva većinu rada sa niskonivojskim socketima i prirodno se integriše sa async/await. Za složene potrebe možete preći na pakete kao što su dio, ali osnovni obrazac ostaje: uputiti asinhroni poziv, sačekati rezultat, ažurirati stanje sa setState() ili vašeg odabranog upravitelja stanja i ponovo izgradite pogođene widgete.
Dodaci, pohrana, Firebase i alati
Na Androidu ste navikli deklarirati zavisnosti u Gradleu; na Flutteru ih deklarirate u pubspec.yaml i preuzmite ih sa pub.dev. Gradle datoteke ispod android/ Folder Flutter projekta uglavnom je namijenjen integracijama specifičnim za platformu ili kada su vam potrebne prilagođene izvorne biblioteke - svakodnevni razvoj aplikacija ostaje u Dartu.
Zajedničke postavke i SQLite također imaju gotove ekvivalente. Gdje Android nudi SharedPreferences za pohranu malih ključeva i vrijednosti i SQLite (ili Room) za strukturirane podatke, Flutter ih oblaže putem dodataka poput shared_preferences i sqfliteOvi dodaci (plugins) objedinjuju ponašanje Androida i iOS-a tako da možete koristiti jedan Dart API bez obzira na platformu, a istovremeno se oslanjati na osnovne nativne implementacije.
Integracija s Firebaseom je slično jednostavna i prvoklasna. Većina Firebase servisa – Authentication, Firestore, Realtime Database, Cloud Messaging, Analytics, Remote Config i drugi – imaju službene Flutter dodatke koje održavaju Firebase i Flutter timovi. Oni odražavaju konceptualni model iz Android Firebase SDK-ova, ali s Dart-idiomatic API-jima. Za više nišnih Firebase funkcija koje nisu direktno obuhvaćene, postoji zdrav ekosistem dodataka trećih strana na pub.dev.
Za otklanjanje grešaka i profiliranje, Flutterov DevTools paket vam pruža bogat set alata koji je direktno uporediv sa profilerom i Layout Inspectorom u Android Studiju. Možete pregledati stablo widgeta, pratiti ponovne izgradnje, nadgledati alokacije memorije, dijagnosticirati curenja i fragmentaciju te proći kroz Dart kod. U kombinaciji s IDE podrškom u Android Studiju i VS Codeu, vrućim ponovnim pokretanjem i vrućim ponovnim pokretanjem, ciklus povratnih informacija u Flutter razvoju djeluje barem jednako čvrsto - a često i čvršće - od onoga na što ste navikli s Composeom.
Push notifikacije, još jedan uobičajeni problem na Androidu, u Flutteru se obrađuju putem dodataka poput firebase_messaging. U suštini, ovi elementi komuniciraju s Firebase Cloud Messagingom i izvornim okvirima za obavještavanje na Androidu i iOS-u, ali logika vaše aplikacije nalazi se u objedinjenom Dart API-ju. Konfiguracija i ponašanja specifična za platformu (poput kanala za obavještavanje na Androidu) i dalje su važni, a vaše postojeće iskustvo s tim detaljima platforme i dalje je vrlo relevantno.
Čak i widgeti za početni ekran na Androidu, koji se ne mogu implementirati isključivo u Flutteru, i dalje se mogu integrirati s Flutter kodom. Obično ih gradite pomoću Jetpack Glance ili XML rasporeda, a zatim koristite paket kao što je home_widget za komunikaciju s vašom Flutter aplikacijom, dijeljenje podataka, pa čak i ugrađivanje rasteriziranog Flutter korisničkog interfejsa kao slike unutar izvornog widgeta. Taj hibridni pristup vam omogućava da zadržite svoje glavno iskustvo u Flutteru, a da pritom poštujete ograničenja platforme.
Gledajući sve ove paralele, Jetpack Compose programer koji ulazi u Flutter uopće ne počinje od nule. Vaše razumijevanje deklarativnog korisničkog interfejsa, životnog ciklusa Androida, navigacije, stanja, resursa i asinhronog rada se vrlo prirodno preslikava na Flutterov svijet; ono što se najviše mijenja su imena, jezik (Dart) i višeplatformski način razmišljanja. Nakon što internalizirate widgete i Navigator kao temeljne koncepte, ostatak steka se obično prilično brzo uklapa.